Generator expressions (Python 2.4+) and list comprehensions (Python 2.0+) differ in the following ways:
Syntax
Syntactically, the difference between the two is that generator expressions are wrapped in parentheses and list comprehensions are wrapped in squared brackets:
# generator expression (item for item in iterable)
# list comprehension [item for item in iterable]
Consider, for example, the following where numbers are squared using generator expression:
squares = list(n ** 2 for n in range(5)) print(squares) # [0, 1, 4, 9, 16]
This is equivalent to the following:
def GenSquare(num): for n in range(num): yield(n ** 2) squares = list(GenSquare(5)) print(squares) # [0, 1, 4, 9, 16]
The same example (of squaring numbers) can be written as list comprehension, for example, like so:
squares = [n ** 2 for n in range(5)] print(squares) # [0, 1, 4, 9, 16]
This is equivalent to the following:
squares = list(map(lambda n: n ** 2, range(5))) print(squares) # [0, 1, 4, 9, 16]
It can also be written in a loop, like so:
squares = [] for n in range(5): squares.append(n ** 2) print(squares) # [0, 1, 4, 9, 16]
Return Type
Generator expressions return a generator object, while list comprehensions return a new list:
# generator syntax squares = (n ** 2 for n in range(5)) print(squares) # <generator object <genexpr> at ...>
# list comprehension squares = [n ** 2 for n in range(5)] print(squares) # [0, 1, 4, 9, 16]
To return a list with generator syntax, you have to explicitly wrap the resulting generator object in a list, for example, like so:
# generator syntax squares = list(n ** 2 for n in range(5)) print(squares) # [0, 1, 4, 9, 16]
Since generator expression return a generator object, it won't support list functions/operations (such as indexing, slicing, etc.) unless you explicitly convert it to a list.
Operation
Generator expressions are more memory efficient than list comprehensions. This is because list comprehension loads the entire list in memory, whereas a generator expression only loads one value in memory at a time. For example, you can check how much memory each of these use by using the sys.getsizeof()
method:
from sys import getsizeof ge = (n for n in range(5000)) ge_size = getsizeof(ge) print(ge_size) # 112 lc = [n for n in range(5000)] lc_size = getsizeof(lc) print(lc_size) # 43032
This means that you can use generator expressions for very large, even infinite, sequences.
Hope you found this post useful. It was published . Please show your love and support by sharing this post.