有一些嵌套字典的数组:
data = [{'id':1, 'name':'test'}, {'id':2, 'name':'test'}, ....., {'id':N, 'name':'test'}]
尝试在id
:
name=test
值
val = [x['id'] for x in data if x['name'] == 'test'][0]
预期结果:val = 1
但有例外:list index out of range
怎么了?
答案 0 :(得分:1)
使用您的(略微编辑的)示例数据,您的代码可以正常使用:
data = [{'id': 1, 'name': 'test'}, {'id': 2, 'name': 'test'}, {'id': 3, 'name': 'test'}]
val = [x['id'] for x in data if x['name'] == 'test'][0]
>>> print(val)
1
但是,如果没有包含与目标字符串匹配的名称的字典:
>>> val = [x['id'] for x in data if x['name'] == 'blah'][0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
这是因为列表推导会创建一个空列表,因为没有d['name']
设置为'blah'
的词典。索引空列表会导致IndexError
异常。这与此相同:
>>> [][0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
解决此问题的一种简单方法是在索引之前检查列表:
matches = [x['id'] for x in data if x['name'] == 'test']
val = matches[0] if matches else None
此处假设None
不能用作id
的值。
另一种更有效的方法,再次假设None
不是有效id
,则使用next()
并使用默认值:
val = next((x['id'] for x in data if x['name'] == 'test'), None)
这使用生成器表达式,避免生成包含匹配词典的整个列表。相反,它只会迭代data
列表,直到找到第一个匹配项,或者data
列表已用尽。
答案 1 :(得分:0)
def getFirstMatchingId(data):
val = [x['id'] for x in data if x['name'] == 'test']
if len(val) >= 1:
val = val[0]
print "Matching ID:-->",val
data = [{'id':1, 'name':'test'}, {'id':2, 'name':'test'}, {'id':3, 'name':'test'}]
getFirstMatchingId(data)
data = [{'id':1, 'name':'test1'}, {'id':2, 'name':'test'}, {'id':3, 'name':'test1'}]
getFirstMatchingId(data)
data = [{'id':1, 'name':'test1'}, {'id':2, 'name':'test1'}, {'id':3, 'name':'test1'}]
getFirstMatchingId(data)
data = []
getFirstMatchingId(data)
以上程序将提供输出
匹配ID: - &gt; 1 匹配ID: - &gt; 2