0

I have a list with a name:

list_123_456 = [1,2,3]

I then use some parts of a filename to recreate the name of this list:

name = 'list_{0}_{1}' .format(filename[0:3],filename[6:9])

This works to the extent that 'name' now equals 'list_123_456' as I wanted it to. But the code is treating it as a string rather than as a list that I defined at the beginning.

For example, if I try:

len(name)

I get the answer '12' (letters in the name) rather that '3' that I would like.

Any help would be great, thank you.

Marcin
  • 48,559
  • 18
  • 128
  • 201
user1551817
  • 6,693
  • 22
  • 72
  • 109
  • That's because `name` is a string. You might want to get the object associated with that variable name, possibly with the use of `eval`, which is not recommended – inspectorG4dget Aug 27 '13 at 19:15
  • 2
    I found 11 independent dups last time I looked, and each one of them links to several others… – abarnert Aug 27 '13 at 19:22

3 Answers3

2

What you're trying to do is almost always a bad idea. If you just create a dictionary, instead of a bunch of separate variables, this is trivial:

lists = {}
lists[('123', '456')] = [1, 2, 3]
# ...

Now, instead of this:

name = 'list_{0}_{1}' .format(filename[0:3],filename[6:9])

… you can just do this:

name = lists[(filename[0:3], filename[6:9])]

You could of course key the dictionary off 'list_123_456' instead of ('123', '456'), or use a two-level nested dict so you can write lists[filename[0:3]][filename[6:9]]… whatever you find most readable.


If you really, really want to do this anyway, you can look up a variable name to get its value if you know the scope you want to evaluate it in, because globals(), locals(), MyClass.__dict__, etc. are always accessible, and they're dictionaries. So:

name_name = 'list_{0}_{1}' .format(filename[0:3],filename[6:9])
name = globals()[name_name]

If worst comes to worst, you can even eval(name_name). But that's an even worse idea.


See this blog post for more details.

abarnert
  • 354,177
  • 51
  • 601
  • 671
1

You can get your the list by name using locals() dictionary:

>>> list_123_456 = [1,2,3]
>>> locals()['list_123_456']
[1, 2, 3]

But this is not a good practice. Instead consider making a dictionary with mapping list names with actual lists:

>>> data = {'list_123_456': list_123_456}
>>> data['list_123_456']
[1, 2, 3]
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
1

But the code is treating it as a string rather than as a list that I defined at the beginning.

That's because it is a string. Strings are not interchangeable with variables (as they are commonly called, although "name" is also a good term).

In general, if you want to look up a piece of data using a computed name (i.e. a string), you should store it in a dict:

byname = {'list_123_456':[1,2,3]}
byname[name] #=> [1,2,3]
Marcin
  • 48,559
  • 18
  • 128
  • 201