Vlad D
Vlad D

Reputation: 454

Return multiple values from list comprehension if any value matches condition

Have array of dictionaries:

a = [{'id': 1, 'k': 1}, {'id': 2, 'k': 2}, {'id': 3, 'k': 3}]

How to return value of id key and value of k if any k matches condition?

Trying like:

return [i['id'], i['k'] if any(i['k'] == 2 for i in a) else fail('fail')]

Upvotes: 0

Views: 1634

Answers (2)

RoadRunner
RoadRunner

Reputation: 26315

I don't think you need to use any() here, as you only need to check one 'k' key in each dictionary, which must be unique to begin with.

First break down the problem into simple code, then worry about list comprehensions later:

a = [{'id': 1, 'k': 1}, {'id': 2, 'k': 2}, {'id': 3, 'k': 3}]

result = []
for d in a:
    if d['k'] == 2:
        result.append((d['id'], d['k']))

if result:
    print(result)
else:
    print('fail')

Which Outputs:

[(2, 2)]

You can easily construct a working list comprehension from here, as shown in @aneroid's answer.

Upvotes: 1

aneroid
aneroid

Reputation: 15987

You can't use any because that checks the full list and returns true if any match, rather than returning the specific item which matches.

Do the list comprehension with a check for each 'k':

>>> a = [{'id': 1, 'k': 1}, {'id': 2, 'k': 2}, {'id': 3, 'k': 3}]
>>> [(x['id'], x['k']) for x in a if x['k'] == 2]
[(2, 2)]

This will return multiple values if more than one 'k' matches:

>>> a = [{'id': 1, 'k': 1}, {'id': 2, 'k': 2}, {'id': 3, 'k': 3}, {'id': 7, 'k':2}]
>>> [(x['id'], x['k']) for x in a if x['k'] == 2]
[(2, 2), (7, 2)]

For a missing value, you'll get an empty list. If you want a 'fail' or some random text instead, which is highly not recommended, do:

>>> [(x['id'], x['k']) for x in a if x['k'] == 9] or 'fail'
'fail'

And if you wanted each dict that matches, the expression is only the 'x' which is the list items (dicts) which matche:

>>> [x for x in a if x['k'] == 2] or 'fail'
[{'k': 2, 'id': 2}, {'k': 2, 'id': 7}]
>>> [x for x in a if x['k'] == 9] or 'fail'
'fail'

Upvotes: 1

Related Questions