Python变量作用域疑问:全局列表被函数修改而整数未改的原因
问题解析:归并排序函数修改全局列表 vs 整数参数不修改全局变量的原因
归并排序代码的逻辑分析
def mergesort(a): #sorting algo #code is alright just confused about scope of variable if(len(a)>1): mid = len(a)//2 l = a[:mid] r = a[mid:] mergesort(l) mergesort(r) i=j=k=0 while(i<len(l) and j<len(r)): if(l[i]>r[j]): a[k] = r[j] j+=1 else: a[k] = l[i] i+=1 k+=1 while(i<len(l)): a[k] = l[i] i+=1 k+=1 while(j<len(r)): a[k] = r[j] j+=1 k+=1 a = [30,2,4,5,-1,3,7,3,9,2,5] mergesort(a) print(a)
函数参数的a确实是局部变量,但它指向的是和全局变量a完全相同的列表对象。列表属于可变对象,当你执行a[k] = ...这类操作时,并没有给局部变量a重新赋值新对象,而是直接修改了这个列表对象内部的元素。因为全局变量和局部变量指向同一个列表,所以全局变量的列表自然会被修改。
整数参数代码的逻辑分析
def foo(a): a=20 a = 10 foo(a) print(a)
整数属于不可变对象,调用foo(a)时,局部变量a拿到的是全局变量a的值的引用,但你无法修改不可变对象本身。当你执行a=20时,实际上是给局部变量a重新赋值了一个全新的整数对象,和原来全局变量指向的10没有任何关系,所以全局变量的值不会改变。
两段代码的核心区别
- 归并排序函数:操作的是可变对象(列表)的内部元素,没有改变局部变量
a的指向,只是修改了原对象的内容,所以全局变量的列表被同步修改。 - foo函数:给局部变量
a重新赋值了新的不可变对象,切断了和原全局变量对象的关联,原对象没有被修改,因此全局变量值不变。
内容的提问来源于stack exchange,提问作者Manoj D Bhat
相关产品推荐
相关产品推荐

