List comprehension - NameError: name '_[1]' is not defined ?

mario ruggier mario.ruggier at
Thu Jan 15 13:52:02 CET 2009

On Jan 15, 12:29 pm, mario ruggier <mario.rugg... at> wrote:
> Any ideas why?
> Note, i'd like that the first parameter to ts() is as independent as
> possible from the context in expression context, a sort of independent
> mini-template. Thus, the i,j enumerate counters would normally not be
> subbed *within* the comprehension itself, but in a similar way to how
> k is evaluated, within the call to ts() -- I added them this way here
> to help follow easier what the execution trail is. Anyhow, within that
> mini-template, i'd like to embed other expressions for the % operator,
> and that may of course also be list comprehensions.

OK, here's the same sample code somewhat simplified
and maybe be easier to follow what may be going on:

class GetItemEvaluator(object):
    def __init__(self):
        self.globals = globals() # some dict (never changes)
        self.globals["ts"] = self.ts
        self.globals["join"] = " ".join
        self.locals = {} # changes on each evaluation
    def __getitem__(self, expr):
        return eval(expr, self.globals, self.locals)
    def ts(self, ts):
        print "ts:", ts, "::::", self.locals
        return ts % self

# one level
gie = GetItemEvaluator()
gie.locals["inner"] = ("a","b","c","d")
TS1 =  """
pre %(join([
for j,k in enumerate(inner)]))s post
OUT1 = TS1 % gie
print "Output 1:", OUT1

# two level
gie = GetItemEvaluator()
gie.locals["outer"] = [ ("m","n","o","p"), ("q","r","s","t")]
TS2 = """
leading %(join([
pre %(join([
for j,k in enumerate(inner)]))s post
''' # identical to TS1, except for additional '%(s)s.'
for i,inner in enumerate(outer)])
)s trailing
OUT2 = TS2 % gie
print "Output 2:", OUT2

As the gie.locals dict is being automagically
updated from within the list comprehension
expression, I simplified the previous call to ts().
Thus, executing this with the prints enabled as
shown will produce the following output:

$ python2.6 scratch/
ts: %(j)s.%(k)s :::: {'_[1]': [], 'k': 'a', 'j': 0, 'inner': ('a',
'b', 'c', 'd')}
ts: %(j)s.%(k)s :::: {'_[1]': ['0.a'], 'k': 'b', 'j': 1, 'inner':
('a', 'b', 'c', 'd')}
ts: %(j)s.%(k)s :::: {'_[1]': ['0.a', '1.b'], 'k': 'c', 'j': 2,
'inner': ('a', 'b', 'c', 'd')}
ts: %(j)s.%(k)s :::: {'_[1]': ['0.a', '1.b', '2.c'], 'k': 'd', 'j': 3,
'inner': ('a', 'b', 'c', 'd')}
Output 1:
pre 0.a 1.b 2.c 3.d post

pre %(join([
for j,k in enumerate(inner)]))s post
:::: {'_[1]': [], 'i': 0, 'outer': [('m', 'n', 'o', 'p'), ('q', 'r',
's', 't')], 'inner': ('m', 'n', 'o', 'p')}
ts: %(i)s.%(j)s.%(k)s :::: {'outer': [('m', 'n', 'o', 'p'), ('q', 'r',
's', 't')], 'i': 0, 'k': 'm', 'j': 0, '_[1]': [], 'inner': ('m', 'n',
'o', 'p')}
ts: %(i)s.%(j)s.%(k)s :::: {'outer': [('m', 'n', 'o', 'p'), ('q', 'r',
's', 't')], 'i': 0, 'k': 'n', 'j': 1, '_[1]': ['0.0.m'], 'inner':
('m', 'n', 'o', 'p')}
ts: %(i)s.%(j)s.%(k)s :::: {'outer': [('m', 'n', 'o', 'p'), ('q', 'r',
's', 't')], 'i': 0, 'k': 'o', 'j': 2, '_[1]': ['0.0.m', '0.1.n'],
'inner': ('m', 'n', 'o', 'p')}
ts: %(i)s.%(j)s.%(k)s :::: {'outer': [('m', 'n', 'o', 'p'), ('q', 'r',
's', 't')], 'i': 0, 'k': 'p', 'j': 3, '_[1]': ['0.0.m', '0.1.n',
'0.2.o'], 'inner': ('m', 'n', 'o', 'p')}
Traceback (most recent call last):
  File "scratch/", line 40, in <module>
    OUT2 = TS2 % gie
  File "scratch/", line 8, in __getitem__
    return eval(expr, self.globals, self.locals)
  File "<string>", line 9, in <module>
NameError: name '_[1]' is not defined

Anyone can help clarify what may be going on?


More information about the Python-list mailing list