lists of variables
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Sat Feb 20 23:21:09 EST 2010
On Sat, 20 Feb 2010 21:25:19 -0600, Michael Pardee wrote:
> I'm relatively new to python and I was very surprised by the following
> behavior:
[snip]
I don't see why. It's fairly unusual behaviour to want, and it would be
surprising if you did this:
def test():
x = 1
mylist = [2, 4, x]
function(mylist)
assert x == 1
and the assertion failed, even though you never passed x to the function.
Such behaviour could easily turn into a never-ending source of bugs.
> So it looks like variables in a list are stored as object references.
Python doesn't store variables in lists, it stores objects, always.
Even Python variables aren't variables *grin*, although it's really
difficult to avoid using the term. Python variables are mappings between
names (strings) and objects, not memory locations.
> 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.
Yes, we talk about name binding (and rebinding) versus mutation. A simple
example:
>>> alist = blist = [] # bind two names to the same list object
>>> alist.append(1) # mutate the list (modify in place)
>>> blist
[1]
>>> alist = alist + [2] # a rebinding operation
>>> blist
[1]
>>> alist
[1, 2]
> I can think of some ways to work around this, including using single
> element lists as "pointers":
Yes, that's a standard way to do it, except that by "standard" I mean
"really really really rare, honestly, hardly anyone does that".
Slightly less rare, but still uncommon, is to wrap objects in an instance:
class Record:
pass
o = Record()
o.x = 1
o.y = 2
modify(o)
print o.x, o.y
Of course you can make the class as fancy, or as simple, as you want.
But a better approach is to take advantage of Python's ability to return
multiple values:
x = 1
y = 2
x, y = modify(x, y)
rather than:
x = 1
y = 2
modify([x, y])
Speaking as an old Pascal coder, you won't miss pass-by-reference very
often.
--
Steven
More information about the Python-list
mailing list