Learning Python / Beginner / Tutorial

Python List Comprehensions II: Lost in NY

A beginner’s guide to Python object comprehensions and protecting your home from a Joe Pesci-type burglar

Joe Marx
Towards Data Science
6 min readDec 10, 2020

--

Photo by Christopher Gower on Unsplash

As you undoubtedly remember from my last article on the subject, list comprehensions allow for more dynamic, readable, and efficient list creation. However, there is far more to a comprehension than just putting items in a list from an existing iterable. We can make more powerful comprehensions by using conditional statements, introducing more than one dummy variable, and leveraging other Python class comprehensions like dictionary comprehensions.

On one condition…

Last time we looked at how to make a basic list comprehension. Now we’re gonna go a bit deeper. Let’s look at our example [x+5 for x in range(6)] from last time. Recall that this loops through the iterable range(6) and adds 5 to each one. We get back a list [5,6,7,8,9,10] . But what if we wanted to add some more power to that statement? What if we wanted a list of only the even numbers? We can do this by adding an if statement to our list comprehension.

First we ask, how can we determine if a number is even? We can use the modulo operator, which divides one number by a second number then returns the remainder. We can use this operator to divide each number by 2 and check if it returns a 0, which would mean it’s even. For example: 24 ÷ 2 = 0 with no remainder so 24 % 2 == 0 returns True. In a list comprehension, if we want to return a list of items that only fit specific qualifications, we add an if statement after the iterable, in the case of our example:

[x+5 for x in range(6) if (x+5) % 2 == 0]Out[0]: [6,8,10]

Note the output list has less items than was in the iterable we looped through.

Or else?

We also can return a list that tells either x + 5 or that it’s odd by adding an else statement after the if statement. PLOT TWIST: however, when you do an if/else statement in a list comprehension, you put it BEFORE the for statement. In this case:

[x+5 if (x + 5) % 2 == 0 else "ODD!" for x in range(6)]Out[0]: ['ODD!', 6, 'ODD!', 8, 'ODD!', 10]

(Why you would want an output list like that is for you to figure out.)

If you try to put an if/else at the end of the list comprehension you’ll get a SyntaxError. Same goes if you try to put JUST an if statement before the for statement. This can be hard to keep straight so one way to remember, is to say out loud the logic of the list comprehension as a sentence.

FIRST though, let’s remind ourselves of a few things: that whatever goes before that for statement gets spit out into your final list. With an if/else statement, either one thing happens or the other, so you’re going to have an entry in your final list for every item in the iterable. The if alone at the end will pare down the number of entries in your final list because it only gets put in it IF it fits your criteria.

So first without conditionals a logic sentence would be:

“Put THIS in my list FOR each ITEM in my ITERABLE.”

With just an if/else statement we’d say:

“Either put THIS in my list IF it’s even, or ELSE put in THIS other thing FOR each ITEM in my ITERABLE.

For just an if statement, we’d say :

“Put THIS in the list FOR each ITEM in my ITERABLE but only IF it’s even.”

Photo by Dmitry Ratushny on Unsplash

Working with Dictionaries as your iterable

If you have a dictionary that you’d like to use as your iterable for a list comprehension there are several ways to do it. If you only want to work with the keys, you can simply call dict.keys() as the item to loop through, whereas you can call dict.values() to have your dummy variable loop through each of the values in the dictionary key, value pair. However, one very powerful use-case is to be able to access both. To do this we call dict.items() to loop through. When we to run this code:

nname = {"Kevin": "Les Incompetants", "Marv_Harry": "StickyBandits"}[x for x in nname.items()]Out[2]: 
[('Kevin', 'Les Incompetants'), ('Marv_Harry', 'StickyBandits')]

Note that the list is made of tuples: the key and the value bound together. We can access them more powerfully by changing our for statement slightly.

nname = {"Kevin": "Les Incompetants", "Marv_Harry": "StickyBandits"}['{} aka {}'.format(key,value) for key, value in nname.items()]Out[2]: 
['Kevin aka Les Incompetants', 'Marv_Harry aka StickyBandits']

Let’s break that code down. We are taking each key/value pair into a string that introduces them by their nicknames. If you haven’t encountered the string.format() method, read about it here and come back. The real power here is that you are able to use the key and value pairs together, create conditionals using them, etc. As we introduce more of these concepts, the expressiveness of our code increases.

Dictionary comprehensions

Ok, now that you are a seasoned professional with list comprehensions, let’s look at how this translates to other comprehensions. The syntax for making a dictionary is incredibly similar. The only difference is there are now two things to write for each entry: a key and a value. Using pseudp-code, you write this as {key: value for dummy variable in iterable}

If you wanted to make a dictionary that had the numbers 1–5 as keys and the corresponding number to the third power as the values you can write that out as {x: x**3 for x in range(1,6)}, this will output {1: 1, 2: 8, 3: 27, 4: 64, 5: 125}.

Let’s put this all together

Ok, let’s see if we can put this all together. Let’s say you were left home by yourself while your family was away on vacation and you’re only 8 years old. Meanwhile, a pair of cartoonish burglars make it clear they know your house is unprotected and they’re gonna break in and rob you. We’ve all been there!

The good news is, you’re not just a violent borderline-sociopathic genius-child, you’re also a programming prodigy. You run several advanced computer break-in simulations on ways you can protect your house and it spits out a Python list of hundreds of defensive maneuvers you can try in your house and the percentage they will permanently injure Joe Pesc — I mean the burglars. You only want a list of the tactics that have over a 75 percent chance of committing irreparable harm on them. Let’s take a look at the first three items from your list:

Ok, so if we want to use code to give us just the names of the tactics that will be most effective, we could want to make a dictionary that has the names of each tactic as a key and its probability as a value.

To do this we can call on the .split() method we used in the first article to divide the words, select the second word (index[1]) and make that a key, then select the first word (index [0]), coerce it to type int then set that to the value. Try doing this on your own before checking your work below.

Now we can bring it all together by doing a list comprehension using the dictionary as an iterable and using a conditional if the dictionary value is greater than 75. Again try this on your own then see below the solution:

Et violà! You run this on the complete list and now you have dozens of options you can use to nearly murder those burglars! You save the house, and with the help of your neighbor who you once thought was scary, those two won’t be able to hurt you ever again until maybe next year under similar circumstances…

Well done!

You’re now an expert on the basics of Python comprehensions! Use these in your code and you’ll have more readable, marginally faster, and more concise code. There are so many use cases for comprehensions, we haven’t scratched the surface, but now you should have the tools to figure them out as they come up. Note there are also generator and set comprehensions that we haven’t touched, but they follow very similar syntax. Thanks for reading, now go write some awesome comprehensions!

--

--