Your code works fine for me using your (slightly edited) sample data:
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
However, if there is no dictionary containing a name that matches the target string:
>>> 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
This is because the list comprehension will create an empty list because there are no dictionaries with d['name']
set to 'blah'
. Indexing an empty list results in the IndexError
exception. It’s the same as doing this:
>>> [][0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
A simple way to fix this is to check the list before indexing it:
matches = [x['id'] for x in data if x['name'] == 'test']
val = matches[0] if matches else None
here it is assumed that None
can not be used as the value for an id
.
Another, more efficient way, again assuming that None
is not a valid id
is to use next()
with a default value:
val = next((x['id'] for x in data if x['name'] == 'test'), None)
This uses a generator expression which avoids generating a whole list containing the matched dictionaries. Instead it will iterate over the data
list only until the first match is found, or the data
list is exhausted.
2
solved Python: return first value by condition of nested dictionary in array [closed]