Python中for循环覆盖列表时[:]切片的作用是什么?
Python普通赋值与切片赋值的差异原理
普通赋值失效的原因
执行for l in my_list时,循环变量l确实和my_list对应位置的子列表指向同一个内存对象,此时id(l) == id(my_list[i])成立。
但执行l = [num for num in l if num % 2 == 0]属于变量重新绑定操作:你是把列表推导式生成的新列表的内存地址,赋值给了循环变量l这个变量本身,整个过程完全不会修改原来l指向的子列表对象,my_list里存储的还是原有子列表的引用,所以最终打印原列表没有变化。
切片赋值生效的原因
l[:] = xxx属于列表对象的就地修改操作,和变量重新绑定逻辑完全不同:
- 当
l[:]出现在赋值符号右侧时,才会生成原列表的浅拷贝对象,这也是你观察到id(l[:])和id(l)不同的原因; - 当
l[:]出现在赋值符号左侧时,代表「对l指向的列表的全部元素位置执行替换操作」,本质是调用列表的__setitem__方法,直接修改原列表内部存储的元素,原列表的内存地址不会发生任何变化。
因此my_list里存储的子列表引用没有变,但子列表本身的内容已经被修改,最终就能得到预期的结果。
简易验证示例
a = [1, 2, 3] b = a # 普通赋值:重新绑定变量b,不会影响原列表a b = [4, 5, 6] print(a) # 输出:[1, 2, 3] # 切片赋值:就地修改b指向的原列表,a也会同步变化 b = a b[:] = [4, 5, 6] print(a) # 输出:[4, 5, 6]
内容的提问来源于stack exchange,提问作者tblznbits
相关产品推荐
相关产品推荐

