Python:通过数组中嵌套字典的条件返回第一个值

时间:2017-09-07 11:34:33

标签: python dictionary

有一些嵌套字典的数组:
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
怎么了?

2 个答案:

答案 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