This post originated from an RSS feed registered with Python Buzz
by maxim khesin.
Original Post: quiz answer
Feed Title: python and the web
Feed URL: http://feeds.feedburner.com/PythonAndTheWeb
Feed Description: blog dedicated to python and the networks we live in
There was a nice amount of response to the Python puzzler I posted. The comments were basically on the right track. I explained the code to myself "old-school style", by mentally backporting it to C++. There are basically two mental steps here. For Step 1, consider this code:
def times2(x): x = x*2
whether you call it with an int
var = 2 times2(var)
or with a list
var = ['two'] times2(var)
the value of var remains unchanged. But is you have a function
plus2(x): x.append('two') lst = [] plus2(lst)
the value of the passed-in list is changed. Explaination? The best definition I found was probably the one by Martellibot: "The terminology problem may be due to the fact that, in python, the value of a name is a reference to an object. So, you always pass the value (no implicity copying), and that value is always a reference." If you want an "old-school" explaination, think of this:
1) void foo(int* px){*px = 2;} int x = 4; foo(&x); 2) void foo(int* px){px = new int(5);} int x = 4; foo(&x);
The value of x changes to 5 in case 1) but remains unchanged in case 2), because while you can utilize the pointer to get at the object x, the pointer itself is just a local variable and can be reassigned to another memory location representing a different value, with the original x unchanged. So while times2 definitely reassignes a new value to the reference, plus2 has no assignment, and is simply calling a method of the original object via the reference. This is Step 1. In Step 2 we have to consider the operator += in particular. On the one hand, it looks like an assignment - x += 1 is equivalent to x = x + 1. On the other hand, if you still remember your C++ weaties, += is implemented as a member function (there are good performance reasons for this). += is actually viewed semantically equivalent to an .append() method. So which one is it it Python? Well, it depends. For lists += is indeed equivalent to append(), hence the original value is changed. But ints are immutable in python. This means that .append() is impossible on ints and assignment semantics must be used for x += 1 when x is int. Well, this is a technical explaination, but I can't say I like the resulting confusion. I do not envy the job of explaining this to some less technical Python users. I do not know if there are any healthier alternatives, but this one is surely bitter.