eval ?

A

Angelo Secchi

I'm trying to use eval (is the right function? ) to generate empty lists
with different names(es. list_1, list_2, list_3, ...) in a loop similar
to:

for index in range(1,4):
list=[]
for index in range(1,7):
if <condition>:
list.append(1)
foo='list_'+str(index)+'=list'
eval(foo)

I am not a programmer as you probably see from the code and I do not
even know if this is the right approach to do that in Python (I used
this structure with Matlab that I want now to dismiss ...)

Any help?
Thanks
angelo
 
C

Cameron Laird

I'm trying to use eval (is the right function? ) to generate empty lists
with different names(es. list_1, list_2, list_3, ...) in a loop similar
to:

for index in range(1,4):
list=[]
for index in range(1,7):
if <condition>:
list.append(1)
foo='list_'+str(index)+'=list'
eval(foo)

I am not a programmer as you probably see from the code and I do not
even know if this is the right approach to do that in Python (I used
this structure with Matlab that I want now to dismiss ...)
.
.
.
Matlab is valuable. Python is even more so. I think your move to Python
will reward you; you'll find new vistas of productivity opening up. It
might interest you to read the references I'm starting to collect in <URL:
http://phaseit.net/claird/comp.programming/open_source_science.html >.

Yes, it's possible to do what you attempt above (although there are
several errors in the particular coding you've chosen), but it's far more
idiomatic to parametrize the lists this way:
my_lists = {}
for counter in range(1,5):
my_lists[counter] = []

I suspect you want to do something more than just initialize my_lists; if
we understood your ultimate goal, it might turn out there's an even better
approach, perhaps one that sets up [] as a default value.
 
C

Chris

One way to do this is:

for index in range(1,4):
list=[]
for index in range(1,7):
if <condition>:
list.append(1)
locals()['list_'+str(index)] = list

Of course this isn't going to work the way you expect, because you're
assigning a pointer to "list" to "list_n" with each iteration, and at the
end, all of your "list_n" variables are going to reference the same object,
the one orginally referenced by "list"

Perhaps you are looking for something like:
dict([('list_'+str(n), [1,]*n) for n in xrange(1,7) if <condition>])

so if condition is "n in (2,4,6)", you'd get output like:
foo = dict([('list_'+str(n), [1]*n) for n in xrange(1,7) if n in (2,4,6)])
foo {'list_2': [1, 1], 'list_6': [1, 1, 1, 1, 1, 1], 'list_4': [1, 1, 1, 1]}
foo['list_4']
[1, 1, 1, 1]

Note that I'm createing a brand new list (via "[1]*n") with each iteration
of the list comprehension, rather than using a reference to a previously
created list.

HTH
Chris

Angelo Secchi said:
I'm trying to use eval (is the right function? ) to generate empty lists
with different names(es. list_1, list_2, list_3, ...) in a loop similar
to:

for index in range(1,4):
list=[]
for index in range(1,7):
if <condition>:
list.append(1)
foo='list_'+str(index)+'=list'
eval(foo)

I am not a programmer as you probably see from the code and I do not
even know if this is the right approach to do that in Python (I used
this structure with Matlab that I want now to dismiss ...)

Any help?
Thanks
angelo
 
M

Mel Wilson

I'm trying to use eval (is the right function? ) to generate empty lists
with different names(es. list_1, list_2, list_3, ...) in a loop similar
to:

for index in range(1,4):
list=[]
for index in range(1,7):
if <condition>:
list.append(1)
foo='list_'+str(index)+'=list'
eval(foo)

I am not a programmer as you probably see from the code and I do not
even know if this is the right approach to do that in Python (I used
this structure with Matlab that I want now to dismiss ...)

I believe you want exec . Do you mean something like:

for i in range (1, 4+1):
li = []
for j in range (1, 7+1):
if (condition):
li.append (1)
exec ("list_%d%d = li[:]" % (i, j,))

(I've improvised out of a few possible problems.
`list` is already used in Python as the type for lists.
It's better to name an actual list something else: `li` for
instance.
It's possible to use `index` for two different things, as
you've done, but frequently each use needs its own name, as
here.
Each run through the `i` loop creates a distinct list,
which is given the name `li`. In the `j` loop this distinct
list is appended to without changing its identity. Unless
you apply your new name to a copy of that list, all your
`list_1x` names will apply to the same list instance.. as will
all your `list_2x` names, all your `list_3x` names, etc. The
`li[:]` construct copies the contents of li into a fresh
list instance each time. This may (or may not) be what you
wanted.)

Regards. Mel.
 
L

Lonnie Princehouse

Hi Angelo,

Welcome to Python =)

Why not make a list of lists? I.e.

lists = [ [] for i in range(3) ]
for my_list in lists:
for i in range(6):
if some_condition(i):
my_list.append(1)

It's generally best to avoid eval if you don't need it. And some tips-

1. Don't use "list" as a variable name. It's a builtin type!

2. Iterate over objects in lists directly, not with an index, unless you
actually need the index for something. Example,
for obj in obj_list:
print obj

instead of

for i in range(len(obj_list)):
print obj_list

3. Don't use the same variable name "index" for both for loops.

4. String formatters!
"list%s = my_list" % index
is more readable than
"list" + str(index) + " = my_list"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top