Python has many special functions that helps us do things in a faster and more optimized way, part of these methods are comprehensions, which are methods that help us create lists and dictionaries faster with the help of loops.

List comprehensions

List comprehensions are handy little methods we can use to “compress” the logic of a simple for loop that ultimately creates a list to a single line of code, however, they are not always easy to read, let’s check the following examples:

1
2
3
4
5
6
7
8
9
# Calculate the square of a list of numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squares = []
for number in numbers:
    squares.append(number ** 2)
print(squares)

# Do the same thing using list comprehension
print([number ** 2 for number in range(1, 101)])

As you can see, we’ve reduced 4 lines of code to just one, that makes this code smaller and more efficient, but at the cost of readability, but let’s break this down. List comprehension can be broken down to the following elements:

VARIABLE = [ EXPRESION for VAR in ITERABLE (condition) ]

That last part is important, comprehensions are done over an iterable (lists, dictionaries, ranges, tuples, etc)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Get the fruits from a list that start with the letter "a"
fruits = ["apple", "banana", "cherry", "durian", "elderberry", "fig", "grape", 
          "honeydew", "apricot", "kiwi", "lemon", "mango", "nectarine", "orange", 
          "avocado"]
fruits_with_a = []
for fruit in fruits:
    if fruit.startswith("a"):
        fruits_with_a.append(fruit)
print(fruits_with_a)

# Now let's do the same with list comprehension
fruits_with_a_2 = [fruit for fruit in fruits if fruit.startswith("a")]
print(fruits_with_a_2)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# A simpler case would be to create a list with the odd numbers from 1 to 100

# Get a list of odd numbers from 1 to 99
numbers = range(1, 10)
odd_numbers = []
for number in numbers:
    if number % 2 != 0:
        odd_numbers.append(number)
print(odd_numbers)

# And let's do that with list comprehensions
odd_numbers2 = [number for number in range(1, 10) if number % 2 != 0]
print(odd_numbers2)


# Another example would be to flatten out nested lists
vec = [[1,2,3], [4,5,6], [7,8,9]]
flat = []
flattened = [num for item in vec for num in item]

for item in vec:
  print(type(item))
  for num in item:
    print(type(num))
    flat.append(num)

print(flat)
print(flattened)

Dictionary comprehensions

Much like list comprehensions, the outcome of a dictionary comprehension is, well, a dictionary. It follows pretty much the same structure as list comprehension except that it takes into consideration the key:value structure that dictionaries have.

VARIABLE = { KEY:VALUE for VAR in ITERABLE }

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Given a list of words, create a dictionary of word lenghts.
words = ['hello', 'world', 'my', 'name', 'is', 'bob', "3", "hello", "again"]
words_with_lenghts = {}
for word in words:
    words_with_lenghts[word] = len(word)
print(words_with_lenghts)

# And let's do it with a dictionary comprehension
words_with_lenghts2 = {word: len(word) for word in words}
print(words_with_lenghts2)

# Now let's create a dictionary with words larger than 3 letters
words_with_lenghts3 = {word: len(word) for word in words if len(word) > 3}
print(words_with_lenghts3)