可能重复:
What is the difference between slice assignment that slices the whole list and direct assignment?
我没有钱上学,所以我正在自学一些Python,同时在高速公路上的收费站工作(长时间的客户很少)。 (顺便说一句:Coursera应翻译成所有语言......)
我在这里读过,如果我有一个列表l
:
l = ['a', '', 'b']
我希望像这样过滤掉空字符串:
l = [c for c in l if c]
或者像这样:
l = filter(lambda x: x, l)
建议改为:
l[:] = ... # either method 1 or method 2 above
不要“丢失”对第一个l
的引用,特别是在其他变量指向它的情况下。
我的问题:
为什么l[:]
在这种情况下表示“l
”的内容,允许专门重新分配给“同一个”l
,而在其他地方我想到它作为“相同大小的切片”,方便为我创建l的副本?
我是否误解如何完全使用l[:]
进行相同列表重新分配?
我认为如果我有一个l
并且我要求l[:]
,那么后者是原始l
的实际副本?
参考:“学习Python” - > 有各种各样的 复制列表的方法,包括使用内置列表功能和标准库 复制模块。也许最常见的方法是从头到尾切片
谢谢!
答案 0 :(得分:3)
Python在获取列表片段和设置列表片段之间存在差异。实际上,它们实际上是单独的操作(分别为__getitem__
和__setitem__
)。因此,对于get,情况可能并非如此。
在前一种情况下,l[:]
表示获取列表的副本(它生成一个全新的列表,其中包含与旧列表相同的内容)。在后一种情况下,l[:] = ...
表示将列表的内容设置为其他内容。
答案 1 :(得分:3)
因为LHS切片运算符基本上说枚举通过此列表并为每个索引分配内容,而RHS运算符说枚举通过此列表,并创建一个值为<的新对象/ em>的
让我们看看它的实际效果:
l[:] = [c for c in l if c!=0] #ignore how stupid this list comprehension is
基本上被分解为:
l[0] = l[0] if l[0] != 0
l[1] = l[1] if l[1] != 0
...
l[n] = l[n] if l[n] != 0
因为你要枚举它并分配值,你不会创建任何新对象 - 只是给l的索引赋予新值。
但是,另一方面,做
l = anything
更改变量l
包含的引用。在那之后,它指向内存中完全不同的对象。
现在,
c = l[:]
会向您提供l
的副本,而不是l
的引用。这必须是真的,否则,
c = l[1:5]
如果要尝试使用与l
相同的对象引用,必须更改l
的值。
答案 2 :(得分:2)
当在赋值的左侧使用切片运算符时,您告诉python将序列存储在列表的选定元素的右侧。
换句话说,您没有替换l
,而是要分配 l
中的元素。