Python List Comprehensions and Generators
List comprehensions provide a concise way to create lists. Generators provide a way to iterate over data without storing it all in memory.
List Comprehensions
List comprehension offers a shorter syntax when you want to create a new list based on the values of an existing list.
Syntax
# newlist = [expression for item in iterable if condition == True]
Examples
fruits = ["apple", "banana", "cherry", "kiwi", "mango"]
# Create a new list containing only fruits with the letter "a"
newlist = [x for x in fruits if "a" in x]
print(newlist)
# Output: ['apple', 'banana', 'mango']
With Conditions
The expression can also contain conditions (ternary operator).
# Return "orange" instead of "banana"
newlist = [x if x != "banana" else "orange" for x in fruits]
Generator Expressions
Generator expressions are similar to list comprehensions, but instead of creating a list, they return a generator object. They use parentheses () instead of brackets [].
Memory Efficiency
Generators are memory efficient because they yield items one by one rather than creating the entire list in memory.
# List comprehension (creates full list in memory)
my_list = [x * x for x in range(1000000)]
# Generator expression (returns an object)
my_gen = (x * x for x in range(1000000))
import sys
print(sys.getsizeof(my_list)) # Large size
print(sys.getsizeof(my_gen)) # Small size (constant)
Generator Functions (yield)
A generator function is defined like a normal function, but whenever it needs to generate a value, it does so with the yield keyword rather than return.
def countdown(num):
print("Starting")
while num > 0:
yield num
num -= 1
val = countdown(5)
print(next(val)) # Starting, 5
print(next(val)) # 4