Issue 34076: Nested loop in dictionary comprehension gives global name not defined inside class (original) (raw)

Created on 2018-07-09 15:57 by con-f-use, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
what_a_dict.py con-f-use,2018-07-09 15:57 More illustrative example
what_a_dict.py con-f-use,2018-07-10 10:56
Messages (6)
msg321326 - (view) Author: Jan Christoph (con-f-use) * Date: 2018-07-09 15:57
The python code: ``` class _tri(object): infts = '(+/-)inf, (+/-)infty, (+/-)infinity' strange_failing = {x+s.replace('(+/-)',''):None for x in ('+','-','') for s in infts.split(', ')} ``` gives a `global name 'infts' is not defined` exception, when normal dictionary comprehensions (without nested loops) and regular nested for-loops work perfectly well. For a complete shell session and more illustrative example in versions 2.7.15 and 3.6.4 see: https://pastebin.ubuntu.com/p/9Pg8DThbsd/
msg321355 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2018-07-10 05:36
I think this is explained in the below answers with example that the left most loop in the comprehension has access to the class variables which the nested comprehensions don't have https://stackoverflow.com/a/22692274/2610955 https://stackoverflow.com/a/13913933/2610955 Thanks
msg321362 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-07-10 07:33
This looks like a duplicate of .
msg321369 - (view) Author: Jan Christoph (con-f-use) * Date: 2018-07-10 08:32
But the simpler dictionary compprehension `{s.replace('(+/-)',''):None for s in infts.split(', ')}` works perfectly. Shouldn't that also give the error if it was a scope issue?
msg321378 - (view) Author: Jan Christoph (con-f-use) * Date: 2018-07-10 10:53
Okay, so we're a in another scope inside the dictionary comprehension (all comprehensions for that matter), and only one symbol is passed to the inside. That's why `strange_reversed_working = {x+s.replace('(+/-)',''):None for x in infts.split(', ') for s in ('+','-','')}` functions, but if you reverse the order it does not. That's a real trap.
msg321379 - (view) Author: Jan Christoph (con-f-use) * Date: 2018-07-10 10:56
Updated example with reversed variable order for reference. This really seems to be related to , but really not the same thing. IMHO both `a` and `b` should be passed in a situation like this: ```` a = range(5) b = range(3) c = [x+y for x in a for y in b] ````
History
Date User Action Args
2022-04-11 14:59:02 admin set github: 78257
2018-07-10 10:56:15 con-f-use set files: + what_a_dict.pymessages: +
2018-07-10 10:53:01 con-f-use set messages: +
2018-07-10 08:32:26 con-f-use set messages: +
2018-07-10 07:33:11 serhiy.storchaka set status: open -> closedsuperseder: improper scope in list comprehension, when used in class declarationnosy: + serhiy.storchakamessages: + resolution: duplicatestage: resolved
2018-07-10 05:36:11 xtreak set nosy: + xtreakmessages: +
2018-07-09 15:57:52 con-f-use create