Python 2.6 automatically turns variables within a function definition global under certain circumstances? Why?
I am absolutely dumbfounded by why the following is happening:
Here is my code:
def add_one(array):
new_array = array
length = len(array)
for i in range(length):
new_array[i] = new_array[i]+1
return new_array
x = [1,2,3,4,5];
y = add_one(x)
print x
print y
Here are the results:
[2, 3, 4, 5, 6]
[2, 3, 4, 5, 6]
I do not understand why x is changed.
My speculations: Somehow x is given as a global variable to the function add_one. I included 'new_array = array' so that if array was somehow the global variable x, x would not be changed. However, somehow new_array also became the global variable x when 'new_array = array' was executed. I wrote an alternate version of the function add_one which did not give me issues:
def add_one(array):
new_array = []
length = len(array)
for i in range(length):
new_array.append(array[i]+1)
It seems that if a local variable (that is a array) is e开发者_开发技巧dited by it's index within a function, it turns global with respect to the global variable that was taken as an input for that function?
I have no idea what is going on. Any explanations would be highly appreciated.
When you say new_array = array
, you're not making a copy of the array, you're simply making another name for the array. Both names still apply to the same array.
To make a copy the simplest way is to use slicing: new_array = array[:]
Nothing is made global for obscure readons. array
is still a perfectly normal local variable. But it's a reference, as everything in Python (well, every name at least) is a reference:
add_one(x)
passes a reference (not like a reference in e.g. C++, more like a pointer - if either of that means anything to you) tox
toadd_one
new_array = array
will just copy that reference- No copying happening, all these names point to the same object!
That means that calling a method on array
in add_one
modified the very same object x
of the caller refers to - re-assigning array
(array = []
) will just overwrite the local copy of the reference and not affect other variables referring to the same object (after all, it's quite possible that there is no such variable!), but member or item assignment (e.g. new_array[i] = ...
) is basically a method call and will modify the object.
Generally, the easiest way to generate a new list from an existing one with some pattern of modification applied to each element and optionally some filtering is using a list comprehension. [x + 1 for x array]
in this example.
On your third line you set y to x.
new_array = array
This line is the crucial one:
new_array = array
You have to see new_array
not as a new variable, but as a new name for the variable (object) which already has the name array
.
精彩评论