Filter a Python list by predicate

I would want to do something like:

>>> lst = [1, 2, 3, 4, 5]
>>> lst.find(lambda x: x % 2 == 0)
2
>>> lst.findall(lambda x: x % 2 == 0)
[2, 4]

Is there anything nearing such behavior in Python’s standard libraries?

I know it’s very easy to roll-your-own here, but I’m looking for a more standard way.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You can use the filter method:

>>> lst = [1, 2, 3, 4, 5]
>>> filter(lambda x: x % 2 == 0, lst)
[2, 4]

or a list comprehension:

>>> lst = [1, 2, 3, 4, 5]
>>> [x for x in lst if x %2 == 0]
[2, 4]

to find a single element, you could try:

>>> next(x for x in lst if x % 2 == 0)
2

Though that would throw an exception if nothing matches, so you’d probably want to wrap it in a try/catch. The () brackets make this a generator expression rather than a list comprehension.

Personally though I’d just use the regular filter/comprehension and take the first element (if there is one).

These raise an exception if nothing is found

filter(lambda x: x % 2 == 0, lst)[0]
[x for x in lst if x %2 == 0][0]

These return empty lists

filter(lambda x: x % 2 == 0, lst)[:1]
[x for x in lst if x %2 == 0][:1]

Method 2

Generators and list comprehensions are more pythonic than chainable functions.

>>> lst = [i for i in range(1, 6)]

>>> lst
[1, 2, 3, 4, 5]

>>> gen = (x for x in lst if x % 10 == 0)

>>> next(gen, 'not_found')
'not_found'

>>> [x for x in gen]
[]

For example, I use it like this sometimes:

>>> n = next((x for x in lst if x % 10 == 0), None)
>>> if n is None:
...     print('Not found')
... 
Not found

Otherwise, you can define your utility function oneliners like this:

>>> find = lambda fun, lst: next((x for x in lst if fun(x)), None)
>>> find(lambda x: x % 10 == 0, lst)
>>> find(lambda x: x % 5 == 0, lst)
5

>>> findall = lambda fun, lst: [x for x in lst if fun(x)]
>>> findall(lambda x: x % 5 == 0, lst)
[5]


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x