views:

204

answers:

4

That was helpful kgiannakakis. I'm facing a problem as below:

a = ['zbc','2.3']
for i in range(0,5):
    exec('E%d=%s' %(i,a[i]))

This results in:

Traceback (most recent call last):
  File "", line 2, in 
    exec('E%d=%s' %(i,a[i]))
  File "", line 1, in 
NameError: name 'zbc' is not defined
A: 

Okay. this code is very weird.

As a one liner like this, it's not syntactically correct, but I suspect you're missing line breaks for some reason. But then it becomes

a = ['zbc','2.3']
for i in range(0,5): 
    exec('E%d=%s' %(i,a[i]))

But that will result in an index error on the reference to a[i] as shown:

>>> a
['zbc', '2.3']
>>> for i in range(0,5):
...    print a[i]
... 
zbc
2.3
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
IndexError: list index out of range

If you avoided that issue, you'd get

exec("E2.3=1")

on the second pass through the lopp, and that's a syntax error too.

Charlie Martin
+2  A: 

It looks like the code you're generating expands to:

E0=zbc
E1=2.3

At the next iteration through the loop, you'll get an IndexError exception because a is only two elements long.

So given the above, you are trying to assign the value of zbc to E0. If zbc doesn't exist (which it seems that it doesn't), then you will get the NameError you mention.

It's hard to determine what you're actually trying to do with this code, so I'm not sure what to recommend. You could assign strings instead:

exec('E%d="%s"' %(i,a[i]))

This would expand to:

E0="zbc"
E1="2.3"

You would still get the IndexError because your array a is not 5 elements long. That should be an easy fix for you.

Greg Hewgill
A: 

It seems you are trying to use the solution marked in this question.

If your goal is access values in a loop, you should just use a list. This weird concept of variable names with numbers in them is not one that should be used in any language. Try this.

vals = ['foo', 'bar', 'blah', 67, -0.4, 'your mom']
for i in range(len(vals)):
    print(vals[i])

That is the correct way to have a list of values indexed by an integer, not putting it in the variable name.

recursive
A: 

Just keep in mind that 'exec' executes whatever string you pass in to it as if you typed it in your .py file or the interpreter.

When debugging exec() related code, it's helpful to log whatever you're about to 'exec' when you run into trouble, if you did that you'd easily have noticed that E0 wasn't being assigned to the string "zbc" but to the non-existent object zbc.

Aside from that, this code sample is really weird.  There are some legitimate uses for parsing strings into instance variables, or objects in other namespaces, most notably when you're coding a highly dynamic class that needs to do sensible stuff with messy input, or needs to setup a bunch of instance variables from a dict or string.  But without context, the code in your question looks like you're avoiding, or don't understand how, to use list() and dict() objects..

I'd recommend telling a bit more about what you're trying to achieve next time you ask a question around something as peculiar as this.  That would give people a good opportunity to suggest a better solution, or –if you're approaching a particular problem in a completely sensible way– prevent a bunch of answers telling you that you're doing something completely wrong.

Dirk Stoop