back to index

Best feature of Python | List Comprehensions


Chapters

0:0
0:39 List Comprehension with Filter
0:52 List Comprehension: Example
1:23 Alternative: Map + Filter
2:16 List Comprehension with Walrus Operator

Whisper Transcript | Transcript Only Page

00:00:00.000 | This is a list comprehension that allows you to define one list in terms of another list
00:00:05.600 | and is reminiscent of set notation from mathematics. The elegance, simplicity,
00:00:10.720 | and power of this notation makes it, in my opinion, the best feature of Python.
00:00:16.240 | Now what does it mean to be a best feature of a programming language? To me, it's a feature that
00:00:20.720 | makes you fall in love with the language and a feature that makes you enjoy programming in a
00:00:25.680 | language for many years. So the basic notation is a for loop over some input list nums and a
00:00:33.440 | function like f of x that computes something for each element x in nums. In addition, there's a
00:00:40.240 | filter conditional like if g of x, some function, some expression that filters the elements of nums
00:00:48.080 | and only keeps the ones that pass this conditional. Let's look at an example input list nums one two
00:00:54.400 | three four. The list comprehension squares each element of nums so x times x for x in nums.
00:01:00.880 | So that creates a list that contains one four nine and sixteen. Simple, beautiful. And now to
00:01:07.440 | add a filter to keep just the even numbers we can add into the filter conditional of the list
00:01:13.040 | comprehension x modula two equals zero. And then the result is the squaring of the elements that
00:01:18.480 | pass the filter which is four and sixteen. Now some would argue that you can achieve the same
00:01:24.400 | kind of results with for loops or more direct comparison is the map and filter functions which
00:01:29.680 | are also available in Python. So what would that look like to square each element in the list? You
00:01:36.320 | can have a lambda function that does the squaring and a map that applies that lambda function to
00:01:42.080 | each element of nums. That's the second line in the code here. And the third line you can add a
00:01:48.000 | filter to that. So first apply a filter with a lambda function that does the modula two equals
00:01:54.800 | zero conditional. And then on top of that on the elements that pass the filter you again do the
00:02:00.240 | map function of the lambda that squares each element. Now I believe this is also beautiful
00:02:06.480 | and powerful notation but to me it's not nearly as elegant and Pythonic and readable as the list
00:02:13.600 | comprehension notation. Now I already did a video on the most controversial Python feature which
00:02:20.560 | in my opinion is the walrus operator. It comes into play nicely with list comprehensions. Now
00:02:25.680 | if we take some difficult to compute function like fibo here which computes the nth element
00:02:30.880 | of the Fibonacci sequence. The one line ternary operator recursive implementation of the function
00:02:37.120 | written by me untested. I'll leave it to you as homework to test if this actually works.
00:02:43.280 | And I threw it in there to give a shout out to two other things I enjoy which is recursion and the
00:02:50.000 | ternary operator. The if else notation of which in Python I think is another beautiful design choice
00:02:57.600 | that makes an otherwise cryptic looking ternary operator actually readable to our human brains.
00:03:03.920 | And so if we take then another definition of nums that goes from one to six. We can create a basic
00:03:10.720 | list comprehension that applies the fibo function to each element of nums resulting in the familiar
00:03:17.040 | Fibonacci sequence of 1 1 2 3 5 8. Now if we wanted to also add a conditional which is where
00:03:22.640 | the walrus operator comes in. We can compute fibo x and assign it to the variable y via the walrus
00:03:30.480 | operators assignment expression and then do the modules two equals zero check to keep just the
00:03:36.240 | even elements of the Fibonacci sequence. And then in the actual output of the list comprehension
00:03:42.000 | we can just use the variable y as opposed to re-computing the fibo function. So the result
00:03:46.640 | of this list comprehension that uses the walrus operator is two and eight. So list comprehension
00:03:52.800 | actually creates a list objects computes all the elements in the list and stores the entire list
00:03:57.600 | of memory while the generator expression stores just the iterable object and computes every
00:04:03.440 | element in the list one at a time as it's being queried. So for most people the list comprehension
00:04:09.040 | is probably the default choice. It's used when the size of the list is not crazy large. Especially
00:04:14.400 | when you want to reiterate over the list multiple times. It is faster than generator expressions
00:04:20.160 | depending on the context. It could be two to three times faster. So speed is essential you want to
00:04:24.560 | use these. And if you need different list methods like especially the slicing notation you should
00:04:30.720 | be using list comprehension. On the other hand you should use generator expressions when the range of
00:04:37.520 | the sequence is large or infinite. Or if you want to construct iteratable generator objects which
00:04:44.080 | are great to impress your friends with. I should mention I'm really grateful for the sponsors that
00:04:49.680 | support these videos and the podcast. In this case 8sleep. So if you enjoy these click the links in
00:04:55.280 | the description to get a discount and to support my efforts. Thanks for listening and remember try
00:05:00.480 | to learn something new every day.
00:05:14.380 | [BLANK_AUDIO]