Explanation of this Python language feature? [x for x in x for x in x] (to flatten a nested list)
Chris Angelico
rosuav at gmail.com
Sat Mar 22 01:05:29 EDT 2014
On Sat, Mar 22, 2014 at 3:47 PM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> Now I'm not sure precisely how Haskell implements this trick, but it
> suggests to me that it creates a different closure each time around the
> loop of the comprehension. That could end up being very expensive.
It needn't be terribly expensive, if you make a "scope stack" or
"scope chain". Imagine, if you will, a system of scopes like this:
current_scope = None
class Scope:
def __init__(self, *a, **kw):
self.names = dict(*a, **kw)
global current_scope
self.parent = current_scope
current_scope = self
def __getitem__(self, name):
try:
return self.names[name]
except KeyError:
if self.parent is None: raise
return self.parent[name]
def __setitem__(self, name, value):
self.names[name] = value
def exit_scope():
global current_scope
current_scope = current_scope.parent
Creating a new scope would be fairly cheap (and a lot more so if this
were implemented in C without the object overhead, of course). Lookups
would scan up through a series of namespaces, same as they currently
do (local, module, builtins), there'd just be more of them. And the
compiler could be smart enough to skip creating a scope if there are
no assignments. There'd need to be some handling in there for the
'nonlocal' keyword, but my expectation is that 'global' is handled by
retaining a reference to the current_scope at module level, and
starting the search there for a LOAD_GLOBAL.
Each iteration of the loop could begin with Scope() and end with
exit_scope(), and there you are, each iteration in its own closable
scope.
I'm not saying it would be a good thing to do - and it'd be a bad fit
for Python, I think, as I said in my other post - but it could be
done.
ChrisA
More information about the Python-list
mailing list