List comprehension

The idea

List comprehension provides a compact way to take a list, do something to the elements (modify, filter, apply a function), and then return the resulting list. See some examples here.

The syntax

List comprehension expressions are embedded in [] as a way to signal that the result is a list. For example:

[num**2 for num in range(10)]
Out[3]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Reading the above statement from right to left, here's what's happening:

range(10) - generate a list

...for num in... iterate through it using num as the iterator variable

num**2 the thing that you're doing to the list. Here, squaring each element.

By including if statements inside list comprehension, you can effectively filter a list for the elements you want (or don't want)

[num**2 for num in range(10) if num %2 ==0]
Out[12]:
[0, 4, 16, 36, 64]

You can also embed multiple lists inside a list-comprehension expression. This is equivalent to nested loops, but I personally find these confusing.

[first+second for first in ['a','b','c'] for second in ['d','e','f']]
Out[13]:
['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf']

Dictionary Comprehension

In addition to list comprehension, Python also implements dictionary comprehension. I include an example for completeness, though I find myself using this quite rarely. The example below checks if a phrase is a pangram,

sentence = "Just a simple little sentence the word lengths of which we can count in one line"
wordLengths = {key: len(key) for key in sentence.split(' ')}
{'a': 1, 'count': 5, 'little': 6, 'word': 4, 'Just': 4, 'sentence': 8, 'simple': 6, 'of': 2, 'we': 2, 'one': 3, 'lengths': 7, 'can': 3, 'which': 5, 'in': 2, 'the': 3, 'line': 4}

Exercises

Find all of the numbers from 1-1000 that are divisible by 9

[num for num in range(1,1001) if num % 9 ==0]
Out[10]:
[9,
 18,
 27,
 36,
 45,
 54,
 63,
 72,
 81,
 90,
 99,
 108,
 117,
 126,
 135,
 144,
 153,
 162,
 171,
 180,
 189,
 198,
 207,
 216,
 225,
 234,
 243,
 252,
 261,
 270,
 279,
 288,
 297,
 306,
 315,
 324,
 333,
 342,
 351,
 360,
 369,
 378,
 387,
 396,
 405,
 414,
 423,
 432,
 441,
 450,
 459,
 468,
 477,
 486,
 495,
 504,
 513,
 522,
 531,
 540,
 549,
 558,
 567,
 576,
 585,
 594,
 603,
 612,
 621,
 630,
 639,
 648,
 657,
 666,
 675,
 684,
 693,
 702,
 711,
 720,
 729,
 738,
 747,
 756,
 765,
 774,
 783,
 792,
 801,
 810,
 819,
 828,
 837,
 846,
 855,
 864,
 873,
 882,
 891,
 900,
 909,
 918,
 927,
 936,
 945,
 954,
 963,
 972,
 981,
 990,
 999]

Generate 100 random numbers in the range 0-1 using one line of code

import random
[random.random() for num in range(100)]
Out[12]:
[0.30038285887800653,
 0.8068608676121372,
 0.18501623151708046,
 0.06400825379612352,
 0.48142566108152396,
 0.6602528067033887,
 0.16818305080458973,
 0.29538622585966035,
 0.4928298184606388,
 0.2494282549500233,
 0.7154901703159035,
 0.4706569800421482,
 0.37551795560730317,
 0.2562505737878181,
 0.38213270217320083,
 0.9355777522907279,
 0.8812859168335222,
 0.30935395037559643,
 0.7440921522929225,
 0.3140663367395595,
 0.40055368628571353,
 0.508511120928683,
 0.8577178933096079,
 0.9584641317010492,
 0.4457223247921731,
 0.9284894090060116,
 0.19101005848787056,
 0.7552020412113069,
 0.6305409085670466,
 0.5619624214446906,
 0.7860818145964547,
 0.11943933212685554,
 0.05971806742805463,
 0.6284547762752576,
 0.4499530587930166,
 0.4807285946005715,
 0.29247664808391993,
 0.990918595214355,
 0.19382785739789887,
 0.921947091892469,
 0.5942899905691458,
 0.18221730799001423,
 0.28642355806137865,
 0.9926090090647068,
 0.2620811349727985,
 0.9866580852216292,
 0.18462919695296454,
 0.024070833648734302,
 0.4183978821491037,
 0.5065216772296162,
 0.2808559139810669,
 0.5689675362205405,
 0.3092707780928309,
 0.02152156913266834,
 0.3470620533997659,
 0.7295071929030806,
 0.04215517442110839,
 0.327106133738682,
 0.12902643273947778,
 0.8320922310309975,
 0.9088649425014437,
 0.23051491860196693,
 0.6942438596309538,
 0.7360639644822417,
 0.875373367977733,
 0.08272697951195707,
 0.6756821234417167,
 0.10994432111406482,
 0.8467812662036726,
 0.9991187183058816,
 0.7931705529833472,
 0.46941871510638766,
 0.8167974146530707,
 0.43034575083494186,
 0.3787042302780732,
 0.6895201817754012,
 0.47287553685169526,
 0.4860061514293683,
 0.4046464903695117,
 0.3646504416742017,
 0.5460446706976356,
 0.590044255895823,
 0.020141585198305667,
 0.7674232704225379,
 0.24911453527274008,
 0.28606095549529886,
 0.021458484681543433,
 0.5584948725350998,
 0.5532446112724092,
 0.3409970942647851,
 0.9757460282563791,
 0.21713421888585216,
 0.5039434184534949,
 0.9218257425065518,
 0.9164624229550201,
 0.49346465042560794,
 0.529150823418107,
 0.6949404766488418,
 0.7579094907353902,
 0.543721900350119]

Generate 100 random integers in the range 1-10 using one line of code

import random
[random.randrange(1,11) for num in range(100)]
Out[26]:
[4,
 3,
 2,
 4,
 4,
 6,
 4,
 3,
 5,
 5,
 10,
 7,
 5,
 6,
 4,
 3,
 8,
 10,
 9,
 10,
 1,
 4,
 1,
 5,
 4,
 9,
 4,
 3,
 9,
 3,
 6,
 3,
 6,
 8,
 8,
 8,
 9,
 8,
 4,
 7,
 6,
 4,
 8,
 4,
 9,
 2,
 8,
 4,
 6,
 2,
 4,
 7,
 5,
 3,
 9,
 6,
 1,
 3,
 7,
 9,
 4,
 5,
 7,
 3,
 10,
 7,
 3,
 2,
 5,
 3,
 5,
 5,
 10,
 6,
 7,
 9,
 10,
 5,
 10,
 1,
 9,
 8,
 10,
 10,
 10,
 3,
 1,
 3,
 9,
 9,
 2,
 8,
 3,
 5,
 2,
 6,
 4,
 2,
 2,
 8]

Return a list of words longer than 3 letters.

Use list comprehension to take sentence and output the words containing more than 3 letters

sentence = 'The Quick Brown Fox Jumped Over The Lazy Dog'
[word for word in sentence.split() if len(word)>3]
Out[29]:
['Quick', 'Brown', 'Jumped', 'Over', 'Lazy']

A list of all consonants

Return a list containing all the consonants in sentence. The consonants don't have to be unique, but the list should not have both uppercas and lowercase letters. You should do this in one line of code.

Use str.isalpha() to check for punctuation. E.g., 'word'.isalpha() returns True while '?'.isalpha() and 'a word'.isalpha() return False
sentence = 'Can you figure out how many CONSONANTS are in this sentence?'
vowels = ['a','e','i','o','u'] 

[letter for letter in sentence.lower() if (letter not in vowels and letter.isalpha())]
#insert your code here
Out[34]:
['c',
 'n',
 'y',
 'f',
 'g',
 'r',
 't',
 'h',
 'w',
 'm',
 'n',
 'y',
 'c',
 'n',
 's',
 'n',
 'n',
 't',
 's',
 'r',
 'n',
 't',
 'h',
 's',
 's',
 'n',
 't',
 'n',
 'c']
#Use a dictionary comprehension to count the length of each word in a sentence. 
sentence = 'Use a dictionary comprehension to count the length of each word in a sentence' 
results = {word:len(word) for word in sentence.split()} 
print(results) 
{'a': 1, 'count': 5, 'Use': 3, 'word': 4, 'dictionary': 10, 'sentence': 8, 'of': 2, 'in': 2, 'to': 2, 'length': 6, 'comprehension': 13, 'each': 4, 'the': 3}

Dictionary refresher

Add a line to the code below to get the average word length in sentence

Hint: `sum(a_list)` returns the sum of the elements in the list
sentence = "Just a simple little sentence the word lengths of which we can count in one line"
wordLengths = {key: len(key) for key in sentence.split(' ')}
sum(wordLengths.values())/float(len(wordLengths.values()))
Out[51]:
1.3333333333333333