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:

https://github.com/gregmalcolm/python_koans

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

  1. 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.”

  2. 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.

  3. Do the previous entirely with a dict comprehension. This should be a one-liner.

  4. 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!

  5. Create sets s2, s3, and s4 that contain numbers from zero through twenty, divisible 2, 3 and 4.

    1. Do this with one set comprehension for each set.

    2. 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.

    3. 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!)