On 08/10/2012 05:19 AM, Mok-Kong Shen wrote: > > In an earlier question about lists, I was told about the issue of > creation of local names in a function. However, I still can't > understand why the program below outputs: > > [999] sss > [999] > > and not two identical lines of output. For both operators "+=" should > anyway work in similar manner in the function xx in my view. > > Thanks for your help in advance. > > M. K. Shen > > ---------------------------------------------------------- > > def xx(list,str): > list+=[999] > str+="sss" > > lista=[] > stra="" > lista+=[999] > stra+="sss" > print(lista,stra) > > listb=[] > strb="" > xx(listb,strb) > print(listb,strb)
I'm rewriting your xx function so it doesn't overwrite reserved words, list and str. def xx(mylist, mystring): mylist += [999] mystring += "xxx" There are a couple of effects you need to understand in order to see what's happening. First, some terminology. You don't assign values in Python, you bind a name or another lvalue to an object. a=650 builds an object of type int, and binds it to the name a. if you then say b=a, you bind b to the *SAME* object, the previously created int object of value 650. It can be useful to print the id() of an object, to convince yourself that they're actually the same. So if you print id(a) and id(b), you'll get the same value. But if you said c=651 and d=651, you'd have two objects, and the two names would be bound to different objects, with different ids. The += operator is an example of an augmented assignment operator. Others that behave the same way include *= -= and so on. The += operator tries to modify the object referred to by the left hand side, by modifying that object in place. If that fails, perhaps because the object is immutable, then it builds a new object, and binds the left side to that new object. So, if you have a list, and you use += to append to it, you still have the same list object, but it's longer now. If you have a string, or an int, or ... that's immutable, then it builds a new one, and binds it to the left side. Now, put those two operations inside a function, and what do we have ? Let's go through the function, looking at what happens. Local parameter mylist gets bound to the list object bound to listb. The object is not copied, it's now bound to new names, one in the global space, one local. When the mylist += statement is executed, it modifies that object, and instantly the global "variable" listb is modified. Local parameter mystring gets bound to the string object bound to strb. We still only have one (immutable) object. When the mystring += statement is executed, it creates a new string object by concatenating the old one and the "xxx" string. At this point, we can print id(mystring) and see that it changed. When the function returns, the local symbols are unbound, and the new string object is discarded since there are no longer any refs. At this point, in top-level code, the listb object has been modified, and the strb one has not; it still is bound to the old value. -- DaveA -- http://mail.python.org/mailman/listinfo/python-list