Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: assign values to variables in a list or object [duplicate]

Tags:

python

I want to do the following:

a = 1
b = 2
c = 3
tom = [a,b,c]
for i in tom:
    i = 6

The desired result is a = 6

The actual result is a = 1

I'm guessing that there is no way to do this without some kind of exec. Correct?

like image 264
Jonathan Mugan Avatar asked Dec 04 '22 18:12

Jonathan Mugan


2 Answers

Initially I misunderstood your question, and I see that kindall got it right. But I think this question shows a need for a more detailed explanation of how Python works. The best way to think about variables in Python is to think of variable names as having arrows attached to them, and values as objects to which those arrows point. Variable names point to objects. So when you do this:

a = 1

You're really saying "a points to 1". And when you do this:

b = a

You're really saying "b points to the same object as a". Under normal circumstances, a variable can't point to another variable name; it can only point at the same object that the other variable points at. So when you do this:

tom = [a, b, c]

You aren't creating a list that points to the variable names a, b, and c; you're creating a list that points to the same objects as a, b, and c. If you change where a points, it has no effect on where tom[0] points. If you change where tom[0] points, it has no effect on where a points.

Now, as others have pointed out, you can programmatically alter the values of variable names, ether using exec as you suggested (not recommended), or by altering globals() (also not recommended). But most of the time, it's just not worth it.

If you really want to do this, my suggestion would be either simply to use a dictionary (as suggested by DzinX) or, for a solution that's closer to the spirit of your question, and still reasonably clean, you could simply use a mutable object. Then you could use getattr and setattr to programmatically alter the attributes of that object like so:

>>> class Foo():
...     pass
... 
>>> f = Foo()
>>> f.a = 1
>>> setattr(f, 'b', 2)
>>> getattr(f, 'a')
1
>>> f.b
2

Generally, the best solution is to just use a dictionary. But occasionally situations might arise in which the above is better.

like image 167
senderle Avatar answered Jan 08 '23 06:01

senderle


tom = [a, b, c] puts the values 1, 2, and 3 into the list. Once these values are in the list, there's no way to know what name(s) are pointing to them. Assuming they are global variables, you could (but almost certainly shouldn't) do this:

tom = ["a", "b", "c"]
for n in tom:
    globals()[n] = 1

Trying to set individual variables in a loop is almost always the wrong approach. The values clearly have something in common, otherwise you wouldn't want to change them all in a loop, so store them in a list (or a dictionary, if you need names for them) and access and change them there, instead of using individual variables.

like image 37
kindall Avatar answered Jan 08 '23 08:01

kindall