Find the first element in Python list that matches some condition
Sometimes you'll have a list in python and you'd like to find the first element in that list that matches some arbitrary condition. We'll see now how to do that.
For our example the condition is very simple, the length of a string being longer than 5 characters.
Oh and if you are interested, I also wrote a solution to find the first matching element using Perl where there is a function called first.
Find first element using a for loop
The first solution that might come to mind is using a for loop. Grammatically I find it strange, but Python has a nice programming technique. You can add an else part to a for-loop and this else part will be executed if the loop finished "normally", without calling break.
examples/python/first_loop.py
animals = ['snake', 'camel', 'etruscan shrew', 'ant', 'hippopotamus', 'giraffe'] for animal in animals: if len(animal) > 5: first = animal break else: first = None print(first) # etruscan shrew
Find first element using filter and next
Another way that is more compact and some people might find nicer is to use the filter function of Python. Usually we use it to create a shorter list of elements meeting some condition. In this case however we don't need to store the result of the filter call in a variable. Instead we can call the next function. This will return the next element returned by the filter object. Which, in our case, will be the first element in the list.
The only issue is that if there were no matching values, this call would raise an exception. Adding a second parameter to the next() call, Python will return that value. None, in our case.
I've added a second copy to the solution in which I've separated the steps: First assigning the result of filter to a variable and then calling next on it. It is there only to make it easier to understand the construct.
examples/python/first_filter.py
animals = ['snake', 'camel', 'etruscan shrew', 'ant', 'hippopotamus', 'giraffe'] first = next(filter(lambda animal: len(animal) > 5, animals), None) print(first) print('-------') filtered_list = filter(lambda animal: len(animal) > 5, animals) print(filtered_list) first = next(filtered_list, None) print(first)
The output will look like this:
etruscan shrew ------- <filter object at 0x7f1519456a00> etruscan shrew
Show the operations
In Python 2 filter would have returned a list already checking all the values of the original list. That would be a waste of time and CPU. The filter function in Python 3 returns a filter object and only executes the filtering condition when the user actually wants to find the next element in the filtered list. You believe me (and the documentation)? Do you want to see it with your own eyes? Fair enough, let's try it.
In this example, instead of a lambda-function I used a function defined using def and in this function I've added a print-statement as well so we can see when it is executed and with what values?
examples/python/first_filter_log.py
animals = ['snake', 'camel', 'etruscan shrew', 'ant', 'hippopotamus', 'giraffe'] def condition(animal): print(f"len({animal})") return len(animal) > 5 first = next(filter(condition, animals), None) print(first)
This is the output:
len(snake) len(camel) len(etruscan shrew) etruscan shrew
As you can see it stopped calling the condition function once it encountered the first matching string.
Etruscan shrew
In case you were wondering the Etruscan shrew is the smallest mammal by mass.
There is a shorter mammal, but this looks better.
Published on 2020-11-30