3

可能重复:
切片整个列表的切片赋值和直接赋值有什么区别?

我没有钱上学,所以我一边在高速公路上的收费站轮班工作,一边自学一些 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

不要“丢失”对 first 的引用l,尤其是在其他变量指向它的情况下。

我的问题:

  • 为什么在这种情况下l[:]表示“的内容l”,允许专门重新分配给“相同” l,而在其他地方我认为它是“相同大小的切片”,方便地为我创建 l 的副本

  • 我是否误解了如何完全使用l[:]相同列表重新分配?

我想如果我有一个l并且我要求一个l[:],后者是原件的实际副本l

参考:《学习Python》->复制列表有多种方法,包括使用内置列表功能和标准库复制模块。也许最常见的方法是从头到尾切片

谢谢!

4

3 回答 3

3

在 Python 中,获取列表的一部分和设置列表的一部分是有区别的。事实上,它们实际上是独立的操作(__getitem____setitem__,分别)。所以,对于 get 的情况来说,对于 set 来说可能是不正确的。

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

于 2012-08-22T17:50:59.417 回答
3

因为 LHS 切片运算符基本上是说通过这个列表枚举并为每个索引分配一些东西,而 RHS 运算符说通过这个列表枚举,并使用这些值创建一个新对象

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

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.

于 2012-08-22T17:56:48.033 回答
2

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

换句话说,您不是在替换l,而是在分配 l.

于 2012-08-22T17:50:53.217 回答