List Comprehensions were introduced to the Python language in PEP-202 to provide a more concise syntactical way to produce lists where map()
, filter()
, for loops
, and if statements
would normally be used.
A list comprehension can be summed up like this:
new_list = [item action for item in existing_list with optional if condition]
This is a Pythonic way of representing in one line, what normally would take 3 lines in a for loop. For example:
for item in list: if condition: item action
Let’s say you have a list of words saved in existing_list like so:
existing_list = ['The', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dogs.']
You could use a for loop to iterate through the list and save the length of each word to a new list. This takes three lines of code. For example:
word_list = [] for item in existing_list: word_list.append(len(item))
Which yields:
[3, 5, 5, 3, 6, 4, 3, 4, 5]
We can use list comprehension here (without a conditional), and we’re down to one line of code. For example:
word_list = [len(item) for item in existing_list]
Which yields:
[3, 5, 5, 3, 6, 4, 3, 4, 5]
Now to extend this example, we can add a conditional. Let’s say we want a list of only the words with a length greater than 3 characters. Using a for loop, we would add a conditional if statement. For example:
over_three = [] for item in existing_list: if len(item) > 3: over_three.append(item) print over_three
Now with list comprehension:
over_three = [item for item in existing_list if len(item) > 3] print over_three
Both methods yield:
['quick', 'brown', 'jumped', 'over', 'lazy', 'dogs.']
One more example, this time using the range()
function:
Let’s say you want to perform a math operation on a range of numbers from 0 to 25. For this example, lets generate a list of the squares of each number. Using a for loop, we could do this like so:
squares = [] for num in range(25): squares.append( num **2 ) print squares
Using list comprehension:
squares = [num **2 for num in range(25)] print squares
Both methods yield:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576]
Now let’s add a conditional so that we get only the results that end in ‘1’.
squares1 = [num **2 for num in range(25) if str(num**2).endswith('1')] print squares1
Which yields:
[1, 81, 121, 361, 441]
How to build a 5 by 6 matrix of random floats:
import random random_matrix = [[random.random() for x in range(5)] for x in range(6)] for r in random_matrix: print r
Which yields:
[0.8105065135499314, 0.8865204268844189, 0.41117784467229923, 0.9693965072402817, 0.04377154159472296] [0.4449164960699984, 0.44640332641180247, 0.20461691125671944, 0.17777546880568984, 0.36790015258108355] [0.3760034086651669, 0.39668698338668795, 0.05160356609769412, 0.32830220357773043, 0.3401325448631197] [0.6261611276967547, 0.2871336278152169, 0.7117654068095559, 0.4853165792408366, 0.8915682478339392] [0.03019253085736151, 0.3430835985441516, 0.10963927711317467, 0.9270460983912879, 0.4967079233264775] [0.4716454274374533, 0.9139922867709204, 0.37298027208003715, 0.7032776930420336, 0.9368315074777497]
How to build a 5 by 6 matrix of random integers:
import random random_matrix = [[random.randint(0,9) for x in range(5)] for x in range(6)] for r in random_matrix: print r
Which yields:
[9, 8, 0, 8, 6] [1, 1, 9, 6, 1] [5, 6, 1, 3, 3] [4, 2, 7, 2, 9] [5, 7, 6, 8, 2] [8, 8, 3, 6, 6]
Some other examples:
# Print only numbers divisible by 2 print [i for i in range(20) if i%2 == 0] # Using two ranges print [x+y for x in [10,30,50] for y in [25,45,65]] # Using a function call def triple(x): return x*3 print [triple(x) for x in range(10) if x%2==0] # Using isdigit() string = "Hello 12345 World" numbers = [x for x in string if x.isdigit()] print numbers # Using lower() and upper() print [x.lower() for x in ["A","B","C"]] print [x.upper() for x in ["a","b","c"]] # First letter in each word existing_list = ['The', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dogs.'] f = [word[0] for word in existing_list] # List Comprehension inside a for loop! for row in [[i*j for i in range(1, 8)] for j in range(1, 4)]: print row