使用列表理解分配给列表[:]

时间:2018-07-02 11:16:07

标签: python list-comprehension slice

来自此答案https://stackoverflow.com/a/1207461/8074522 我试图找出使用

的区别
somelist = [1,2,3,4,5,6,7,8,9]
somelist = [x for x in somelist if x>4]
and 
somelist[:] = [x for x in somelist if x>4]

他的回答是

  

或者,通过将切片分配给somelist [:],您可以更改现有的   列出仅包含您想要的项目:

“仅包含” <我可以使用分配给某列表而不进行切片。

那么somelist有什么需要[:] here?

2 个答案:

答案 0 :(得分:1)

@jonsharpe在评论中给出了简洁的答案,但为了清楚地说明这一点:

分配一个新列表。失去对旧列表对象的引用,并创建一个的对象:

>>> lst1 = [[1, 2, 3],[4, 5, 6]]
>>> lst2 = lst1
>>> lst1 = [[7,8,9]]
>>> lst1 is lst2
False
>>> lst1
[[7, 8, 9]]
>>> lst2
[[1, 2, 3], [4, 5, 6]]

指定切片。 替换列表(或列表的一部分,取决于切片是什么),并保持相同的对象。

>>> lst1 = [[1, 2, 3],[4, 5, 6]]
>>> lst2 = lst1
>>> lst1[:] = [[7,8,9]]
>>> lst1 is lst2
True
>>> lst1
[[7, 8, 9]]
>>> lst2
[[7, 8, 9]]

答案 1 :(得分:1)

类似somelist = [1,2,3,4,5,6,7,8,9]的说明会创建一个新列表将其(整个列表)分配给您的变量(somelist)。

第二种情况,somelist = [x for x in somelist if x>4]只是过滤for循环将此列表中的每个元素分配给一个临时变量x

然后(在此循环内)if检查此(当前)元素是否满足 在某些情况下,是否大于4。

只有这样,此元素才会添加到新数组中,最后将是 分配给somelist

现在,普通分配和(somelist之间有什么区别) 和切片分配(至somelist[:])。

想象一下,最初有otherList,而您创建了somelist 使用普通分配:somelist = otherList

实际上,没有再创建第二个列表,但是somelist可以被认为是 另一个“指向”第一个列表的指针。

换句话说,otherListsomelist都指向同一内部的 对象(在这种情况下为数组)。

然后,在代码的后面,如果您使用somelist[:] = ...,请编写新内容 到相同内部对象,因此也可以使用otherList看到此新内容 (例如,在代码的其他部分)。

但是,如果您使用普通分配(somelist = ...),则:

  • 已创建一个 new 内部对象(数组)和somelist个点 就是这个。
  • 内容仍显示为otherList

因此,如 jonrsharpe 所指出的,决定使用哪个选项取决于 有关您的应用程序真正需要的内容。

在最简单的情况下,如果没有其他变量指向“旧” 数组,您可以使用普通分配(恕我直言,这是更自然的选择), 旧数组(现在没有任何其他变量的引用)将是垃圾 收集。