From: Steven D'Aprano on
On Sun, 04 Apr 2010 05:50:01 -0700, Ethan Furman wrote:

>>>Yes, this has been fixed in later revisions, but I'm curious to know
>>>what led you to believe that a list comprehension created a new scope.
>>>I don't that was ever promised.
>>
>>
>> Common sense about how programming languages should work? As confirmed
>> by later revisions?
>
> Common sense? About *somebody else's* idea of how a programming
> language should work?

Nevertheless, it is a common intuition that the list comp variable should
*not* be exposed outside of the list comp, and that the for-loop variable
should. Perhaps it makes no sense, but it is very common -- I've never
heard of anyone being surprised that the for-loop variable is exposed,
but I've seen many people surprised by the fact that list-comps do expose
their loop variable.



--
Steven
From: Steven D'Aprano on
On Sun, 04 Apr 2010 14:50:54 -0700, Paul Rubin wrote:

> Alain Ketterlin <alain(a)dpt-info.u-strasbg.fr> writes:
>> d[r] = [r for r in [4,5,6]]
>> THe problem is that the "r" in d[r] somehow captures the value of the
>> "r" in the list comprehension, and somehow kills the loop interator.
>
> Yes, this is a well known design error in Python 2.x. The 3.x series
> fixes this error but introduces other errors of its own.


Oh, do tell?


--
Steven
From: Stephen Hansen on
On 2010-04-04 17:01:20 -0700, Steven D'Aprano said:

> On Sun, 04 Apr 2010 05:50:01 -0700, Ethan Furman wrote:
>
>>>> Yes, this has been fixed in later revisions, but I'm curious to know
>>>> what led you to believe that a list comprehension created a new scope.
>>>> I don't that was ever promised.
>>>
>>>
>>> Common sense about how programming languages should work? As confirmed
>>> by later revisions?
>>
>> Common sense? About *somebody else's* idea of how a programming
>> language should work?
>
> Nevertheless, it is a common intuition that the list comp variable should
> *not* be exposed outside of the list comp, and that the for-loop variable
> should. Perhaps it makes no sense, but it is very common -- I've never
> heard of anyone being surprised that the for-loop variable is exposed,
> but I've seen many people surprised by the fact that list-comps do expose
> their loop variable.

IMHO, the real confusion-point of the situation wasn't so much list
comps vs for loops, but that list comps did expose it, but gen comps
didn't. If one thinks about how each would most likely be implemented
they wouldn't be surprised, but I'm glad the behavior was harmonized in
3.x.

That said, I can't quite imagine how anyone could really sit down and
write code which would be broken by list comps "leaking". The example
code in this thread is just nutty. Even if list comps did create a new
scope, why in the world would you intentionally shadow an enclosing
iteration variable?

Obfuscation is not a good goal to go after :)

--
--S

.... p.s: change the ".invalid" to ".com" in email address to reply privately.

From: Stephen Hansen on
On 2010-04-04 14:50:54 -0700, Paul Rubin said:

> Alain Ketterlin <alain(a)dpt-info.u-strasbg.fr> writes:
>> d[r] = [r for r in [4,5,6]]
>> THe problem is that the "r" in d[r] somehow captures the value of the
>> "r" in the list comprehension, and somehow kills the loop interator.
>
> Yes, this is a well known design error in Python 2.x. The 3.x series
> fixes this error but introduces other errors of its own. It is evil
> enough that I almost always use this syntax instead:
>
> d[r] = list(r for r in [4,5,6])
>
> that works in 3.x and the later releases of 2.x. In early 2.x (maybe up
> to 2.2) it throws an error at compile time rather than at run time.


I have a dramatic suggestion.

Why not use this syntax:

d[r] = [something_else for something_else in [4,5,6]]

Where something_else is basically any conceivable name in the whole
wide world which does not have meaning in the current local scope.

Just for clarity's sake, not sharing names is swell.

--
--S

.... p.s: change the ".invalid" to ".com" in email address to reply privately.

From: Alain Ketterlin on
Alain Ketterlin <alain(a)dpt-info.u-strasbg.fr> writes:

> d = dict()
> for r in [1,2,3]:
> d[r] = [r for r in [4,5,6]]
> print d

Thanks to Chris and Paul for the details (the list comp. r actually
leaks). I should have found this by myself.

My background is more on functional programming languages, that's why I
thought the list comprehension iterator should be purely local. And yes,
I think a "classical" for-loop iterator should also be local to the
loop, but I understand this may be too counter-intuitive to many :-)

-- Alain.