为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PIPIONE 2019-02-17 18:45:36
下面两个函数: 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)

所以,切片赋值语句能够修改列表对象,而普通的赋值语句无法修改列表对象。

查看完整回答
反对 回复 2019-03-01
?
跃然一笑

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]
查看完整回答
反对 回复 2019-03-01
  • 2 回答
  • 0 关注
  • 538 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信