lists of variables

Carl Banks pavlovevidence at gmail.com
Sun Feb 21 07:31:44 CET 2010


On Feb 20, 7:25 pm, Michael Pardee <python-l... at open-sense.com> wrote:
> I'm relatively new to python and I was very surprised by the following behavior:
>
> >>> a=1
> >>> b=2
> >>> mylist=[a,b]
> >>> print mylist
> [1, 2]
> >>> a=3
> >>> print mylist
>
> [1, 2]
>
> Whoah!  Are python lists only for literals?  Nope:
>
> >>> c={}
> >>> d={}
> >>> mydlist=[c,d]
> >>> print mydlist
> [{}, {}]
> >>> c['x']=1
> >>> print mydlist
>
> [{'x': 1}, {}]
>
> So it looks like variables in a list are stored as object references.
> This seems to confirm that:
>
> mydlist[1]['y']=4>>> print mydlist
>
> [{}, {'y': 4}]
>
> So I figure my initial example doesn't work because if you assign a
> literal to something it is changing the object.  But modifying a list
> or dict (as long as you don't re-construct it) does not change the
> object.

All correct, very observant for a Python newbie.

To be more

immutable



> I can think of some ways to work around this, including using single
> element lists as "pointers":
>
> >>> aa=[1]
> >>> bb=[2]
> >>> myplist=[aa,bb]
> >>> print myplist
> [[1], [2]]
> >>> aa[0]=3
> >>> print myplist
>
> [[3], [2]]
>
> But what would be "the python way" to accomplish "list of variables"
> functionality?

Python doesn't have variable references (except in a limited way; see
below), so unless you want to use lists as pointers, I'd recommend
rethinking the problem.  Occasionally I feel like I'd like to be able
to do this, but usually another way exists that is, at worst, slightly
more complex.

For some cases the easiest thing is to make all the variables you're
interested in listing attributes of an object (or values of a dict).
Then store a list of names (or keys).

class X(object): pass
x = X()
x.foo = 1
x.bar = 2
s = ["foo","bar"]
setattr(x,s[0],3)
print x.foo # prints 3

A rule of thumb in deciding whether to use attributes is whether you
will typically know their names in your code ahead of time; if so
storing the values as attributes is a good idea.  If you are inputing
or calculating the names, then it's better to use a dict.


** The one place where Python does have references is when accessing
variables in an enclosing scope (not counting module-level).  But
these references aren't objects, so you can't store them in a list, so
it can't help you:

def f():
    s = []
    a = 1
    def g():
        print a
        s.append(a)
    g() # prints 1
    a = 2
    g() # prints 2: g's a is a reference to f's a
    print s # prints [1,2] not [2,2]


Carl Banks



More information about the Python-list mailing list