冒号运算符在x = myList [:] vs myList [:] = x中的行为

时间:2012-08-22 17:48:40

标签: python list-comprehension slice

  

可能重复:
  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” - > 有各种各样的 复制列表的方法,包括使用内置列表功能和标准库 复制模块。也许最常见的方法是从头到尾切片

谢谢!

3 个答案:

答案 0 :(得分:3)

Python在获取列表片段和设置列表片段之间存在差异。实际上,它们实际上是单独的操作(分别为__getitem____setitem__)。因此,对于get,情况可能并非如此。

在前一种情况下,l[:]表示获取列表的副本(它生成一个全新的列表,其中包含与旧列表相同的内容)。在后一种情况下,l[:] = ...表示将列表的内容设置为其他内容。

答案 1 :(得分:3)

因为LHS切片运算符基本上说枚举通过此列表并为每个索引分配内容,而RHS运算符说枚举通过此列表,并创建一个值为<的新对象/ em>的

让我们看看它的实际效果:

LHS

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包含的引用。在那之后,它指向内存中完全不同的对象。

RHS

现在,

c = l[:]

会向您提供l的副本,而不是l的引用。这必须是真的,否则,

c = l[1:5]
如果要尝试使用与l相同的对象引用,

必须更改l的值。

答案 2 :(得分:2)

当在赋值的左侧使用切片运算符时,您告诉python将序列存储在列表的选定元素的右侧。

换句话说,您没有替换l,而是要分配 l中的元素。