Search code examples
pythoncallgenerator

Use str.join with generator expression in python


When I read the question Python string.join(list) on object array rather than string array, I find the following sentence:

', '.join(str(x) for x in list)

I have already know about (str(x) for x in list) is a generator expression, I also know generator is an iterable. The following code verify the correctness of my view.

>>> gen = (x for x in [1,2,3])
<generator object <genexpr> at 0x104349b40>
>>> from collections import Iterable
>>> isinstance(gen, Iterable)
True

At the same time, str.join(iterable) return a string which is the concatenation of the strings in the iterable. So the following works fine as I wish.

>>> ",".join((str(x) for x in [1,2,3]))
'123'

Then here comes the question, why the code works fine too at bellow, why don't need a parentheses in the function call.

', '.join(str(x) for x in [1,2,3])

After all, str(x) for x in [1,2,3] itself is not a generator.

>>> tmp = str(x) for x in [1,2,3]
  File "<stdin>", line 1
    tmp = str(x) for x in [1,2,3]
                   ^
SyntaxError: invalid syntax

Solution

  • This was specified when generator expressions were introduced (PEP 289):

    if a function call has a single positional argument, it can be a generator expression without extra parentheses, but in all other cases you have to parenthesize it.

    In your case it's a single positional argument, so both ways are possible:

    ', '.join(str(x) for x in [1,2,3])
    ', '.join((str(x) for x in [1,2,3]))