[Patches] [ python-Patches-1660500 ] Hide iteration variable in list comprehensions

SourceForge.net noreply at sourceforge.net
Sat Apr 14 10:40:47 CEST 2007


Patches item #1660500, was opened at 2007-02-15 21:29
Message generated for change (Comment added) made by ncoghlan
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1660500&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Parser/Compiler
Group: Python 3000
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Nick Coghlan (ncoghlan)
Assigned to: Georg Brandl (gbrandl)
Summary: Hide iteration variable in list comprehensions

Initial Comment:
This patch hides the iteration variable in list comprehensions.
It adds new tests (modelled on the generator expression tests) and also removes some del statements from the standard library (where code previously cleaned up its own namespace).
The changes to symtable.[ch] are more significant than strictly necessary - I found it necessary to spend some time cleaning up the code in order to understand what was needed for the list comprehension changes. Given that the 2.x and 3.0 compilers have already diverged fairly significantly, I don't believe this will make the process of keeping them in sync any more difficult than it is already.

Assigning to Georg for initial review (as his set comprehensions patch provided a great deal of inspiration for this one).

----------------------------------------------------------------------

>Comment By: Nick Coghlan (ncoghlan)
Date: 2007-04-14 18:40

Message:
Logged In: YES 
user_id=1038590
Originator: YES

I've uploaded a new version of the patch that is compatible with the py3k
SVN branch as of April 14.

The patch still includes the various cleanups I made to the symbol table
processing while working out how to make this change (use sets where
appropriate, avoid using the same variable name to refer to completely
different things, make a couple of syntax error messages more explicit).

The slowdown should be fixed at the cost of a single function call - the
shorter the sequence being iterated over, the greater the percentage
slowdown that will be. The speed of generator expressions should actually
be (very) marginally increased as they now skip the SETUP_LOOP/POP_BLOCK
steps in the same fashion as list comprehensions always have.
File Added: new-comps-updated.diff

----------------------------------------------------------------------

Comment By: Nick Coghlan (ncoghlan)
Date: 2007-03-12 22:17

Message:
Logged In: YES 
user_id=1038590
Originator: YES

The patch for 'nonlocal' was applied since Georg & I started working on
this. It's going to take me a bit of fiddling to update the patch so that
the parser/compiler stage play well with each other (I really should have
just believed the patch utility when it reported a conflict trying to patch
symtable.c).

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2007-03-08 08:56

Message:
Logged In: YES 
user_id=6380
Originator: NO

Can't say that slowdown bothers me much, if it's typical.

However I think you need to do a svn up in your workspace and regenerate
the patch; I get FAILED message from patch on all the generated files and a
few others: graminit.[ch], symtable.[ch], Python-ast.c, symbol.py.

----------------------------------------------------------------------

Comment By: Georg Brandl (gbrandl)
Date: 2007-02-26 20:30

Message:
Logged In: YES 
user_id=849994
Originator: NO

Okay, I looked at the patch, and apart from a refleak in one of the
compiler methods I couldn't find anything wrong.
I then manually applied the rest of my set comprehension patch. The result
is attached.

Grammar, AST and compilation for comprehensions are now really unified.

It passes the tests for listcomps, genexps and setcomps.

I couldn't check properly for refleaks since e.g. test_genexps leaks in
the branch head, as well as some other tests. I'm currently searching for
the offending revision(s)...
File Added: new-set-comps.diff

----------------------------------------------------------------------

Comment By: Nick Coghlan (ncoghlan)
Date: 2007-02-15 22:13

Message:
Logged In: YES 
user_id=1038590
Originator: YES

For reference, the original set comprehensions patch & the py3k list
discussion:
  http://www.python.org/sf/1548388
  http://mail.python.org/pipermail/python-3000/2006-December/005188.html

Note that the current patch ended up looking a *lot* like the original one
(the main difference specific to list comprehensions is that the temporary
list is built in the inner scope and then returned rather than being passed
in as an argument. Additionally, the code has been unified only for the
symtable stage - the AST and compilation stages still use separate code for
listcomps and genexps).

It turns out that there are some really curly scoping problems that using
a nested function deals with automatically (see the new test_listcomps.py
in the patch for examples). Having a more efficient mechanism specifically
for 'transient' scopes like this is an interesting idea, but it's far from
easy (mainly because the variables in the scope still need to be properly
visible in scopes it *contains*).

Adding set comprehensions on top of this patch should be pretty
straightforward.

----------------------------------------------------------------------

Comment By: Nick Coghlan (ncoghlan)
Date: 2007-02-15 21:53

Message:
Logged In: YES 
user_id=1038590
Originator: YES

Speed measurements show a significant speed up over trunk & Python 2.4 for
module/class level code:

(Python 2.4)$ python -m timeit -s "seq=range(1000)" "[[x for x in seq] for
y in seq]"
10 loops, best of 3: 239 msec per loop
(Python 2.x trunk)$ ./python -m timeit -s "seq=range(1000)" "[[x for x in
seq] for y in seq]"
10 loops, best of 3: 193 msec per loop
(Python 3000)$ ./python -m timeit -s "seq=range(1000)" "[[x for x in seq]
for y in seq]"
10 loops, best of 3: 176 msec per loop

This is almost certainly due to the variables and the list object becoming
function locals.

There is a slowdown inside a function (but we are still faster than Python
2.4):

(Python 2.4)$ python -m timeit -s "seq=range(1000)" -s "def f(): return
[[x for x in seq] for y in seq]" "f()"
10 loops, best of 3: 259 msec per loop
(Python 2.x trunk)$ ./python -m timeit -s "seq=range(1000)" -s "def f():
return [[x for x in seq] for y in seq]" "f()"
10 loops, best of 3: 176 msec per loop
(Python 3000)$ ./python -m timeit -s "seq=range(1000)" -s "def f(): return
[[x for x in seq] for y in seq]" "f()"
10 loops, best of 3: 185 msec per loop


----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1660500&group_id=5470


More information about the Patches mailing list