This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: list/generator comprehension parser doesn't match spec
Type: behavior Stage:
Components: Interpreter Core Versions: Python 2.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: amaury.forgeotdarc, kousu, lehmannro
Priority: normal Keywords:

Created on 2008-04-01 19:19 by kousu, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (4)
msg64818 - (view) Author: Nick Guenther (kousu) Date: 2008-04-01 19:19
I think I've found a bug in python's list comprehension parser. Observe:

>>> [e for i in j in ['a','b','c']]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'j' is not defined

Now, according to the grammar at http://docs.python.org/ref/lists.html,
a list comprehension is (condensed for clarity):
list_comprehension 	::= 	expression list_for
list_for 	::= 	"for" target_list "in" old_expression_list [list_for]

So a list comprehension should always be 
[.... for ... in .... for ... in ... for ... in ...]
(that is, alternating 'for's and 'in's) but here I have a test case that
python happily tries to run that looks like
[... for ... in ... in ....]
msg64819 - (view) Author: Robert Lehmann (lehmannro) * Date: 2008-04-01 20:04
Your example is parsed as [e for i in (j in ['a','b','c'])] and since
`j` is not defined, you get a NameError. If it was defined, you would
still be iterating a boolean (which is not defined).

Grammatically, this is the following (just the important parts, again):
list_comprehension ::=  expression list_for
list_for ::=  "for" target_list "in" old_expression_list
old_expression_list ::= old_expression
old_expression ::= <stripped test hierarchy...> comparison
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "in"

So your basic misconception is that both `in` keywords are belonging to
the list comprehension syntax -- the former does while the latter is
simply an operator.
msg64823 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-04-01 20:56
Indeed; your sample is equivalent to:

temp = (j in ['a','b','c'])        # the "contains" operator
[e for i in temp]                  # basic list comprehension

Even if not meaningful, this code is syntactically correct.
msg64861 - (view) Author: Nick Guenther (kousu) Date: 2008-04-02 15:33
Oh, okay. That's really confusing because I expect "in" to always return
a bool, but in the spirit of python there's no reason it should I guess.
History
Date User Action Args
2022-04-11 14:56:32adminsetgithub: 46781
2008-04-02 15:33:02koususetmessages: + msg64861
2008-04-01 20:56:04amaury.forgeotdarcsetstatus: open -> closed
resolution: not a bug
messages: + msg64823
nosy: + amaury.forgeotdarc
2008-04-01 20:04:42lehmannrosetnosy: + lehmannro
messages: + msg64819
2008-04-01 19:19:09kousucreate