Comprehensions Lab
Goal
Getting familiar with list, set and dict comprehensions.
List Comprehensions
Note: this is a bit of a “backwards” exercise. We show you code and then you figure out what it does.
As a result, there is not much to submit. Don’t worry about it. You’ll have a chance to use these in other exercises.
>>> feast = ['lambs', 'sloths', 'orangutans',
'breakfast cereals', 'fruit bats']
>>> comprehension = [delicacy.capitalize() for delicacy in feast]
What is the output of this?
>>> comprehension[0]
???
>>> comprehension[2]
???
Figure it out before you try it.
Filtering Lists With List Comprehensions
>>> feast = ['spam', 'sloths', 'orangutans', 'breakfast cereals',
'fruit bats']
>>> comp = [delicacy for delicacy in feast if len(delicacy) > 6]
What is the output of this?
>>> len(feast)
???
>>> len(comp)
???
Figure it out first, before trying!
Unpacking Tuples in List Comprehensions
>>> list_of_tuples = [(1, 'lumberjack'), (2, 'inquisition'), (4, 'spam')]
>>> comprehension = [ skit * number for number, skit in list_of_tuples ]
What is the output of this?
>>> comprehension[0]
???
>>> len(comprehension[2])
???
Double List Comprehensions
>>> eggs = ['poached egg', 'fried egg']
>>> meats = ['lite spam', 'ham spam', 'fried spam']
>>> comprehension = \
[ '{0} and {1}'.format(egg, meat) for egg in eggs for meat in meats]
What is the output of this?
>>> len(comprehension)
???
>>> comprehension[0]
???
Set Comprehensions
>>> comprehension = { c for c in 'aabbbcccc'}
What is the output of this?
>>> comprehension
???
Dictionary Comprehensions
>>> dict_of_weapons = {'first': 'fear',
'second': 'surprise',
'third':'ruthless efficiency',
'forth':'fanatical devotion',
'fifth': None}
>>> dict_comprehension = \
{ k.upper(): weapon for k, weapon in dict_of_weapons.items() if weapon}
What is the output of this?
>>> 'first' in dict_comprehension
???
>>> 'FIRST' in dict_comprehension
???
>>> len(dict_of_weapons)
???
>>> len(dict_comprehension)
???
Other Resources
See also:
https://github.com/gregmalcolm/python_koans/blob/master/koans/about_comprehension.py
From Greg Malcolm’s excellent Python Koans series:
Count Even Numbers
This is from CodingBat “count_evens” (http://codingbat.com/prob/p189616)
Using a list comprehension, return the number of even integers in the given list.
Note: the % “mod” operator computes the remainder, e.g. 5 % 2
is 1.
count_evens([2, 1, 2, 3, 4]) == 3
count_evens([2, 2, 0]) == 3
count_evens([1, 3, 5]) == 0
Can you do this with a single line comprehension?
def count_evens(nums):
one_line_comprehension_here
dict
and set
Comprehensions
Revisiting the dict/set lab, see how much you can do with comprehensions instead: Dictionary and Set Lab
Specifically, look at these:
First a slightly bigger, more interesting, or at least bigger, dict:
food_prefs = {"name": "Chris",
"city": "Seattle",
"cake": "chocolate",
"fruit": "mango",
"salad": "greek",
"pasta": "lasagna"}
Working With This dict
Print the dict by passing it to a string format method, so that you get something like:
“Chris is from Seattle, and he likes chocolate cake, mango fruit, greek salad, and lasagna pasta.”
Using a list comprehension, build a dictionary of numbers from zero to fifteen and the hexadecimal equivalent. String is fine. The
hex()
function gives you the hexidecimal representation of a number as a string.Do the previous entirely with a dict comprehension. This should be a one-liner.
Using the dictionary from item (1), make a dictionary using the same keys but with the number of ‘a’s in each value. You can do this either by editing the dict in place, or making a new one. If you edit in place make a copy first!
Create sets s2, s3, and s4 that contain numbers from zero through twenty, divisible 2, 3 and 4.
Do this with one set comprehension for each set.
What if you had a lot more than 3? – Don’t Repeat Yourself (DRY).
Create a sequence that holds all the divisors you might want. It could be 2,3,4, or could be any other arbitrary divisors.
Loop through that sequence to build the sets up – so no repeated code. You will end up with a list of sets – one set for each divisor in your sequence.
The idea here is that when you see three (Or more!) lines of code that are almost identical, then you you want to find a way to generalize that code and have it act on a set of inputs, so the actual code is only written once.
For extra credit, do it all as a one-liner by nesting a set comprehension inside a list comprehension. (OK, maybe this is getting carried away!)