78

Is there a way I can generate variable names in python in a loop and assign values to them? For example, if I have

prices = [5, 12, 45]

I want

price1 = 5
price2 = 12
price3 = 45

Can I do this in a loop or something instead of manually assigning price1 = prices[0], price2 = prices[1] etc.

Thank you.

EDIT

Many people suggested that I write a reason for requiring this. First, there have been times where I have thought this may be more convenient than using a list...I don't remember exactly when, but I think I have thought of using this when there are many levels of nesting. For example, if one has a list of lists of lists, defining variables in the above way may help reduce the level of nesting. Second, today I thought of this when trying to learn use of Pytables. I just came across Pytables and I saw that when defining the structure of a table, the column names and types are described in the following manner:

class TableFormat(tables.IsDescription):
    firstColumnName = StringCol(16)
    secondColumnName = StringCol(16)
    thirdColumnName = StringCol(16)

If I have 100 columns, typing the name of each column explicitly seems a lot of work. So, I wondered whether there is a way to generate these column names on the fly.

6
  • 26
    Why would you want to do that? Commented Oct 24, 2010 at 22:40
  • 11
    Men invented lists.. so you don't have to do this. Commented Oct 24, 2010 at 23:45
  • This is a major code smell! What is you goal here? What are you going to do with "price94" when you've got it? Commented Oct 25, 2010 at 1:47
  • 1
    is the use case something like this: you have some code that accepts some data and crunches it and the output is, e.g., some predicted value for Y? And you don't know how many predicted values you need (and t/4 how many variable assignments) because that depends on the size of the input array, which can vary). Commented Oct 25, 2010 at 1:52
  • 2
    Another use case, meta-programming. github.com/apache/incubator-airflow creates DAGs like so, github.com/apache/incubator-airflow/blob/master/airflow/…. If you want to create an up or downstream dependency, you do it by the variable name you assign. Commented Sep 19, 2016 at 12:27

6 Answers 6

52

If you really want to create them on the fly you can assign to the dict that is returned by either globals() or locals() depending on what namespace you want to create them in:

globals()['somevar'] = 'someval'
print somevar  # prints 'someval'

But I wouldn't recommend doing that. In general, avoid global variables. Using locals() often just obscures what you are really doing. Instead, create your own dict and assign to it.

mydict = {}
mydict['somevar'] = 'someval'
print mydict['somevar']

Learn the python zen; run this and grok it well:

>>> import this
Sign up to request clarification or add additional context in comments.

1 Comment

assigning to locals() does not necessarily work, stackoverflow.com/questions/8028708/…
38

Though I don't see much point, here it is:

for i in xrange(0, len(prices)):
    exec("price%d = %s" % (i + 1, repr(prices[i])));

7 Comments

What's the indentation of the generated code? And when is it generated? Can't make this to work in a Django project
Oh, you mean generating actual code as opposed to executing every separate thing? Just replace that exec() with a print() then.
What is the purpose of using repr() ?
@Bodhidarma: See the description in Python docs --- repr() attempts to return a value that, when passed to eval() (or exec() in this case), yields an object with the same value. In case of strings, it escapes them properly. THAT SAID, you should practically never use the above code (Python has a perfectly good concept for representing a bunch of variables --- lists!).
Note that this won't work in a function -- at least not today, can't remember if it did back in the Dark Ages. Since most Python code should probably not be at module level, it doesn't work where most code will live.
|
26

On an object, you can achieve this with setattr

>>> class A(object): pass
>>> a=A()
>>> setattr(a, "hello1", 5)
>>> a.hello1
5

1 Comment

to get attribute list: "a.__dict__.keys()" or full Dict "a.__dict__"
13

I got your problem , and here is my answer:

prices = [5, 12, 45]

for i in range(1,4):
  vars()["price"+str(i)]=prices[i-1]
  print ("price"+str(i)+" = " +str(vars()["price"+str(i)]))

so while printing:

price1 = 5 
price2 = 12
price3 = 45

4 Comments

This does not work.
There are multiple bugs in here, but the approach as such is not completely flawed; you can assign vars()["prices"+str(i)] and have a variable with the expected name.
Yes, there were a few bugs, but this works: prices = [5, 12, 45] list=['_a','_b','_c'] for i in range(0,3): vars()["prices"+list[i]]= prices[i] print (prices_a) print (prices_b) print (prices_c)
TypeError: can only concatenate str (not "int") to str
8

Another example, which is really a variation of another answer, in that it uses a dictionary too:

>>> vr={} 
... for num in range(1,4): 
...     vr[str(num)] = 5 + num
...     
>>> print vr["3"]
8
>>> 

4 Comments

how do you modify vr though? your solution defeats the whole purpose. i'm scraping data off the web, with which i need to create instances of a class for each container item and the quantity of container items is unknown... like in question 2 in this thread that i created
@Anthony the question that I am answering here is much more focused than what you have linked to. I have no advice to offer on that question.
it's basically the same context. i was referring to the "Question #2" in that thread at the very bottom...
But this, strictly speaking, is not a dynamic assigned variable, is just a dictionary.
3

bit long, it works i guess...

prices = [5, 12, 45]
names = []
for i, _ in enumerate(prices):
    names.append("price"+str(i+1))
dict = {}
for name, price in zip(names, prices):
    dict[name] = price
for item in dict:
    print(item, "=", dict[item])

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.