2

This following part is copied from the official, complete Python 3 grammar .

arglist: argument (',' argument)*  [',']

argument: ( test [comp_for] |
            test ':=' test |
            test '=' test |
            '**' test |
            '*' test )

comp_iter: comp_for | comp_if
sync_comp_for: 'for' exprlist 'in' or_test [comp_iter]
comp_for: [ASYNC] sync_comp_for
comp_if: 'if' test_nocond [comp_iter]

(arglist is used in multiple places where you'd pass arguments to a function call or class definition).

I am confused by the rule argument : test [comp_for]. As . for . in . generators are already valid derivations of test, this seems to imply that a for as a function argument has a special meaning.

my_function(x for x in range(3))

However, just playing around with this definition always interpreted it as the usual generator object that is created by the described syntax.

y = (x for x in range(3))
my_function(y)

So, is there actually anything special about that syntax? Or is it just legacy / future reserved code?

Andreas T
  • 733
  • 7
  • 22
  • 1
    Does this answer your question? [One-line python for loop as function argument](https://stackoverflow.com/questions/48205442/one-line-python-for-loop-as-function-argument) – Georgy Feb 03 '20 at 13:08
  • @Georgy So the entire point of that rule is to allow the coder to skip the second pair of parantheses? – Andreas T Feb 03 '20 at 13:11
  • @Georgy This question is specifically about why the grammar seems to allow two derivations of the same thing. It's not a duplicate of that one. – kaya3 Feb 03 '20 at 13:24

1 Answers1

2

(x for x in range(3)) is a generator expression, which is derived from the test non-terminal. But x for x in range(3) is not derived from test; the parentheses are necessary. So without the argument : test [comp_for] production, sum((x for x in range(3))) would be a valid function call, but not sum(x for x in range(3)).

On the other hand, sum(x for x in range(3)) cannot be parsed in any other way, and the syntax seems less cluttered than the version with extra parentheses. So when generator expressions were introduced in Python 2.4, the syntax for argument lists was modified to make the syntactic sugar possible -- but only when the generator expression is the only argument.

You can find a longer description of the change in PEP 289.

rici
  • 234,347
  • 28
  • 237
  • 341