Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Constructing List Comprehensions

For more information on concepts covered in this lesson, you can check out:

00:00 List comprehensions. List comprehensions are great for constructing and filtering lists. They clearly state the intent of the code and are usually efficient in terms of speed.

00:13 There’s one list comprehension use case where the walrus operator can be particularly useful. Let’s say you want to apply some computationally expensive function—let’s call it slow() in this case—to the elements in your list and filter on the resulting values.

00:29 You could do something like the code seen onscreen. Notice here that the slow code is being simulated with a simple time delay.

00:58 Here, you filter the numbers list and leave the positive results from applying slow(). The problem with this code is that this expensive function is called twice.

01:08 A very common solution for this kind of situation is rewriting the code to use an explicit for loop.

01:41 This now only calls slow() once per number. Unfortunately, the code is now more verbose and the intent of it is harder to understand. The list comprehension clearly signaled that you were creating a new list, while this is more concealed in the explicit for loop since several lines of code separate the list creation and the use of .append(). Additionally, the list comprehension runs faster than the repeated calls to .append().

02:07 It’s possible to code some other solutions, such as using a filter() expression or a double list comprehension.

02:40 The good news with both of these solutions is that there’s only one call to slow() for each number. The bad news is the code’s readability has suffered in both expressions.

02:52 Figuring out what’s actually happening in the double list comprehension takes a fair amount of head-scratching. Essentially, the second for statement is used only to give the name value to the return value of slow(num). Fortunately, that sounds like something that can be performed with an assignment expression instead.

03:12 You can rewrite the list comprehension using the walrus operator as seen onscreen. Note that the parentheses around the assignment expression are required.

03:31 This version is effective, readable, and communicates the intent of the code well. Note that you need to add the assignment expression on the if clause of the list comprehension. If you try to define value with the other call to slow(), then it won’t work.

04:02 This raises a NameError because the if clause is evaluated before the expression at the beginning of the comprehension. Next, let’s look at a slightly more involved and practical example.

04:15 Let’s say you want to use the Real Python feed to find the titles of the latest episode of the Real Python Podcast. You can use the Real Python Feed Reader to download information about the latest Real Python publications.

04:30 In order to find the podcast episode titles, you’ll be using the Parse package. Start by installing them into your virtual environment. You can now read the latest titles published by Real Python.

05:03 Note that for clarity we’re only seeing the last three publications. Podcast titles start with "The Real Python Podcast", so here you can create a pattern that Parse can use to identify them.

05:23 Note that you’ll probably need to copy and paste the text as seen onscreen because the dash is actually an em dash, which isn’t the minus sign that you typically type with your keyboard.

05:48 Compiling the pattern beforehand speeds up later comparisons, especially when you want to match the same pattern over and over. You can check if a string matches your pattern using either pattern.parse() or pattern.search().

06:06 Note that Parse is able to pick out the podcast episode number and the episode name. The episode number is converted to an integer data type because you used the :d format specifier.

06:20 Let’s get back to the task at hand. In order to list all the recent podcast titles, you need to check whether each string matches your pattern and then parse out the episode title. A first attempt might look something like this.

07:29 Although it works, you might notice the same problem you saw earlier. You’re parsing each title twice because you filter out titles that match your pattern and then use that same pattern to pick out the episode title.

07:44 As you did earlier, you can avoid the double work by rewriting the list comprehension using either an explicit for loop or a double list comprehension, but using the walrus operator is even more straightforward.

08:10 Assignment expressions work well to simplify these kinds of list comprehensions. They help you keep your code readable while you avoid doing a potentially expensive operation twice. In this section, you focused on examples where list comprehensions can be rewritten using the walrus operator. The same principles also apply if you see that you need to repeat an operation in a dictionary comprehension, a set comprehension, or a generator expression.

08:40 This next example uses a generator expression to calculate the average length of episode titles that are over 50 characters long.

09:13 The generator expression uses an assignment expression to avoid calculating the length of each episode title twice. Now that you’ve seen the walrus operator in action in list comprehensions, in the next section, you’ll see it operating in a while loop.

Become a Member to join the conversation.