Set & Dict Comprehensions

Set Comprehensions

So we’ve learned about list comprehensions and generator expressions. What if we want to use a comprehension but create a set?

We could do this:

>>> words = ["apple", "orange", "lime", "lemon"]
>>> first_letters = set(w[0] for w in words)
>>> first_letters
{'o', 'a', 'l'}

Here we’ve used a generator expression and the set constructor to make a set.

But Python actually has a special syntax just for making set comprehensions:

>>> first_letters = {w[0] for w in words}
>>> first_letters
{'o', 'a', 'l'}

We use curly braces when making a set comprehension because we use curly braces when making a set.

Dict Comprehensions

What about making a dictionary from a generator expression?

Let’s say we have a dictionary where the values are numbers and we want to make a new dictionary which has only values with two digit numbers.

>>> favorite_numbers = {'rebecca': 293, 'ronald': 76, 'dorothy': 62, 'harold': 36, 'matt': 314}
>>> dict((k, v) for k, v in favorite_numbers.items() if v < 100)
{'ronald': 76, 'harold': 36, 'dorothy': 62}

Here we’re using a generator expression and a dict constructor to make a dictionary.

Python has a special syntax for creating dictionary comprehensions that we should use instead:

>>> {k: v for k, v in favorite_numbers.items() if v < 100}
{'ronald': 76, 'harold': 36, 'dorothy': 62}

Notice the k: v syntax which is very similar to the key-value syntax used for defining dictionaries.

Let’s create a dictionary where the keys are letters and the values are the indexes of those letters (where a is 1 and z is 26):

>>> from string import ascii_lowercase
>>> letters = {letter: n + 1 for n, letter in enumerate(ascii_lowercase)}
>>> letters['t']
20
>>> word = "Trey"
>>> encoded_word = [letters[x] for x in word.lower()]
>>> encoded_word
[20, 18, 5, 25]

More Comprehension Exercises

ASCII Strings

Create a function that accepts a list of strings and returns a dictionary containing the strings as keys and a list of corresponding ASCII character codes as values.

>>> words = ["hello", "bye", "yes", "no", "python"]
>>> get_ascii_codes(words)
{'yes': [121, 101, 115], 'hello': [104, 101, 108, 108, 111], 'python': [112, 121, 116, 104, 111, 110], 'no': [110, 111], 'bye': [98, 121, 101]}

Factors

Create a function which takes a set of numbers and makes a dictionary containing the numbers as keys and all factors as values.

>>> get_all_factors({1, 2, 3, 4})
{1: [1], 2: [1, 2], 3: [1, 3], 4: [1, 2, 4]}
>>> get_all_factors({62, 293, 314})
{314: [1, 2, 157, 314], 293: [1, 293], 62: [1, 2, 31, 62]}

Hint

You can use this function to find the factors of any number:

def get_factors(number):
    return [n for n in range(1, number + 1) if number % n == 0]

Flipped Dictionary

Make a function flip_dict, that flips dictionary keys and values.

Example usage:

>>> flip_dict({'Python': "2015-09-15", 'Java': "2015-09-14", 'C': "2015-09-13"})
{'2015-09-13': 'C', '2015-09-15': 'Python', '2015-09-14': 'Java'}

Most common

Create a function that accepts any number of sets and returns a set of the most common items from each of the given sets.

For example:

>>> most_common({1, 2}, {2, 3}, {3, 4})
{2, 3}
>>> restaurants_trey = {'Habaneros', 'Karl Strauss', 'Opera', 'Punjabi Tandoor'}
>>> restaurants_diane = {'Siam Nara', 'Punjabi Tandoor', 'Opera'}
>>> restaurants_peter = {'Karl Strauss', 'Opera', 'Habaneros'}
>>> most_common(restaurants_trey, restaurants_diane, restaurants_peter)
{'Opera'}

X marks the spot

  • Create a string containing the Declaration of Independence
  • Find all words in the Declaration of Independence that contain the letter “x”

All Together

Write a function all_together that takes any number of iterables and strings them together. Try using a generator expression to do it.

Example:

>>> list(all_together([1, 2], (3, 4), "hello"))
[1, 2, 3, 4, 'h', 'e', 'l', 'l', 'o']
>>> nums = all_together([1, 2], (3, 4))
>>> list(all_together(nums, nums))
[1, 2, 3, 4]

Perfect Cube

A perfect cube is a number which has a cube-root which is an integer.

You can use this function to determine whether a number is a perfect cube:

def is_perfect_cube(n):
    return round(n ** (1/3)) ** 3 == n

Find the first perfect cube over 100,000,000.