Populate a list with a for loop :
nums = [12, 8, 21, 3, 16]
new_nums = []
for num in nums:
new_nums.append(num + 1)
print(new_nums)
->
[13, 9, 22, 4, 17]We can do that in only one line with a list comprehension !
nums = [12, 8, 21, 3, 16] new_nums = [num + 1 for num in nums] print(new_nums) -> [13, 9, 22, 4, 17]
Now a list comprehension with range() :
result = [num for num in range(11)] print(result) -> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
List comprehensions :
- Collapse for loops for building lists into a single line
Components :
- iterable
- iterator variable (represent members of iterable)
- Output expression
Nested loops :
pairs_1 = []
for num1 in range(0, 2):
for num2 in range(6, 8):
pairs_1.append(num1, num2)
print(pairs_1)
->
[(0, 6), (0, 7), (1, 6), (1, 7)]
How to do it now with a list comprehension
pairs_2 = [(num1, num2) for num1 in range(0, 2) for num2 in range(6,8)] print(pairs_2) -> [(0, 6), (0, 7), (1, 6), (1, 7)]
The tradeoff is readibility as it is a bit difficult to understand the line.
Some examples from the exercises :
# Create list comprehension: squares
squares = [num**2 for num in range(10)]
# Create a 5 x 5 matrix using a list of lists: matrix
matrix = [[col for col in range(5)] for row in range(5) ]
# Print the matrix
for row in matrix:
print(row)
->
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]Advanced comprehensions
Conditionals in comprehensions :
[num ** 2 for num in range(10) if num % 2 == 0] -> [0, 4, 16, 36, 64]
Conditionals on the output expression
[num ** 2 if num % 2 == 0 else 0 for num in range(10)] -> [0, 0, 4, 0, 16, 0, 36, 0, 64, 0]
Dict comprehensions
Use curly braces {} instead of brackets []
You put the key first then : and then the value you want to put
pos_neg = {num: -num for num in range(9)}
print(pos_neg)
{0: 0, 1: -1, 2: -2, 3: -3, 4: -4, 5: -5, 6: -6, 7: -7, 8: -8}From the exercises
# Create a list of strings: fellowship
fellowship = ['frodo', 'samwise', 'merry', 'aragorn', 'legolas', 'boromir', 'gimli']
# Create list comprehension: new_fellowship
new_fellowship = [member for member in fellowship if len(member)>=7]
# Print the new list
print(new_fellowship)
# Create a list of strings: fellowship
fellowship = ['frodo', 'samwise', 'merry', 'aragorn', 'legolas', 'boromir', 'gimli']
# Create dict comprehension: new_fellowship
new_fellowship = {member:len(member) for member in fellowship}
# Print the new dictionary
print(new_fellowship)
Generator expressions
To use generators, you basically do like a list comprehension but you use ( ) instead of brackets [ ]
(2 * num for num in range(10)) -><generator object <genexpr> at 0x1046bf888>
List comprehensions vs generators
- List comprehensions – returns a list
- Generators – returns a generator object
- Both can be iterated over
Printing values from generators
result = (num for num in range(6))
for num in result:
print(num)
->
0
1
2
3
4
5
result = (num for num in range(6))
print(list(result))
->
[0, 1, 2, 3, 4, 5]it’s a bit like when we talked about iter( ). we can use a generator to stock a very big number :
[num for num in range(10**10000)] -> Your session has been disconnected (num for num in range(10**100000)] <generator object..
Conditions in generator expressions
even_nums = (num for num in range(10) if num % 2 == 0) print(list(even_nums)) -> [0, 2, 4, 6, 8]
Generator functions
- Produces generator objects when called
- Defined like a regular function – def
- Yields a sequence of values instead of returning a single value
- Generates a value with yield keyword
Build a generator function :
def num_sequence(n):
"""Generate values from 0 to n."""
i = 0
while i < n:
yield i
i += 1Use a generator function :
result = num_sequence(5)
print(type(result))
->
<class 'generator'>
for item in result:
print(item)
0
1
2
3
4From exercises : we can loop on a list to create a generator
# Create a list of strings: lannister
lannister = ['cersei', 'jaime', 'tywin', 'tyrion', 'joffrey']
# Create a generator object: lengths
lengths = (len(person) for person in lannister)
# Iterate over and print the values in lengths
for value in lengths:
print(value)
And now with a function with a yield :
# Create a list of strings
lannister = ['cersei', 'jaime', 'tywin', 'tyrion', 'joffrey']
# Define generator function get_lengths
def get_lengths(input_list):
"""Generator function that yields the
length of the strings in input_list."""
# Yield the length of a string
for person in input_list:
yield len(person)
# Print the values generated by get_lengths()
for value in get_lengths(lannister):
print(value)RECAP
Basic [output expression for iterator variable in iterable] Advanced [output expression + conditional on output for iterator variable in iterable + conditional on iterable]