Using generator expressions and comprehensions
We can think of simple generator expressions as an operator with three operands. The syntax for these three operands parallels the for
statement:
(expression for target in source)
We specify an expression which is evaluated for each value assigned to a target variable from a source. There are more complex generators, which we'll look at later.
Generator expressions can be used freely in Python. They can be used anywhere in a sequence or a collection that is meaningful.
It's important to note that a generator expression is lazy, or "non-strict." It doesn't actually calculate anything until some consuming operation demands values from it. To see this, we can try to evaluate a generator expression at the REPL:
>>> (2*x+1 for x in range(5)) <generator object <genexpr> at 0x1023981e0>
Python tells us only that we've created a generator object. Since we didn't write an expression to consume the values, all we saw was the object, passively...