下面两个函数:
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。望不吝赐教 谢谢!
2 回答
MMMHUHU
TA贡献1834条经验 获得超8个赞
首先,你需要理解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)
所以,切片赋值语句能够修改列表对象,而普通的赋值语句无法修改列表对象。
跃然一笑
TA贡献1826条经验 获得超6个赞
赋值操作是产生了一个新的对象,而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]
添加回答
举报
0/150
提交
取消