I submitted a pull request with this code:
my_sum = sum([x for x in range(10)])
One of the reviewers suggested this instead:
my_sum = sum(x for x in range(10))
(the difference is just that the square braces are missing).
I was surprised that the second form seems to be identical. But when I tried to use it in other contexts where the first one works, it fails:
y = x for x in range(10)
^ SyntaxError !!!
Are the two forms identical? Is there any important reason for why the square braces aren't necessary in the function? Or is this just something that I have to know?
This is a generator expression. To get it to work in the standalone case, use braces:
and y becomes a generator. You can iterate over generators, so it works where an iterable is expected, such as the
sum
function.Usage examples and pitfalls:
Be careful when keeping generators around, you can only go through them once. So after the above, if you try to use
sum
again, this will happen:So if you pass a generator where actually a list or a set or something similar is expected, you have to be careful. If the function or class stores the argument and tries to iterate over it multiple times, you will run into problems. For example consider this:
it will fail if you hand it a generator:
You can easily get a list from the values a generator produces:
You can use this to fix the previous example:
However keep in mind that if you build a list from a generator, you will need to store every value. This might use a lot more memory in situations where you have lots of items.
Why use a generator in your situation?
The much lower memory consumption is the reason why
sum(generator expression)
is better thansum(list)
: The generator version only has to store a single value, while the list-variant has to store N values. Therefore you should always use a generator where you don't risk side-effects.They are not identical.
The first form,
is a list comprehension. The other is a generator expression and written thus:
It returns a generator, not a list.
If the generator expression is the only argument in a function call, its parentheses can be skipped.
See PEP 289
Read this PEP: 289
Use brace product a generator:
First one is list comprehnsion Where second one is generator expression
Use brace for generators: