list类型全局变量函数内修改问题。

下面两个函数:

def func1(x):
    x = list(set(x))
    return len(x)
def func2(x):
    x[:len(x)] = list(set(x))
    return len(x)

-->L = [0,0,1,2,3]
-->func1(L)
4 
-->L
[0,0,1,2,3] # l并未改变

-->func2(L)
4
-->l
[0,1,2,3] # l改变

我知道func2为何会改变L, 但是不知道为何func1不改变L。
望不吝赐教 谢谢!

PIPIONE
浏览 539回答 2
2回答

MMMHUHU

首先,你需要理解python中【赋值语句】的行为。跟C语言不同,python中的【var=value】读作“把var变量标签分配给value对象”,而不是反过来。 >>> foo=[1,2,3] >>> bar=foo >>> id(foo), id(bar) (2899313114056, 2899313114056) 上述代码可见,两个变量具有相同的内存地址,这在C语言中是不可想象的。python中的变量就只是个名字,没有自己的地址、类型和值,它只能通过“附着”在【对象】上,临时获得后者的地址、类型和值。 然后,你要理解【foo[index]=value】并非普通的赋值语句,而是在背后调用了foo.__setitem__(index, value)方法。 >>> foo, id(foo) ([1, 2, 3], 2899313114056) >>> foo[0]=4 >>> foo, id(foo) ([4, 2, 3], 2899313114056) >>> foo.__setitem__(0, 5) >>> foo, id(foo) ([5, 2, 3], 2899313114056) 所以,切片赋值语句能够修改列表对象,而普通的赋值语句无法修改列表对象。

跃然一笑

赋值操作是产生了一个新的对象,而L原对象并没有发生变化。切片操作是在原有的对象上进行操作,对L元对象进行了重新赋值。 def func1(x): print(id(x)) x = list(set(x)) print(id(x)) return len(x) def func2(x): print(id(x)) x[:len(x)] = list(set(x)) print(id(x)) return len(x) L = [0,0,1,2,3] 分别调用func1,func2查看L的内存地址 func1赋值 产生了一个新的对象 func1(L) 139912186104520 139912185279368 4 L [0,0,1,2,3] func2切片,在原对象上进行修改 func2(L) 139912186104520 139912186104520 4 L [0, 1, 2, 3]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python