python - 赋值给切片避免了修改列表被迭代的错误

时间:2014-02-10 02:17:27

标签: python

我读了here并且通过错误的代码了解到迭代列表和更改循环中的列表元素存在问题。他们建议一种方法是创建列表副本:

for x in a[:]: # make a slice copy of the entire list
    if len(x) > 6: a.insert(0, x)

引用列表的片段是否会创建为执行循环而创建的临时副本?

在以下案例中找到了here

somelist[:] = [x for x in somelist if not determine(x)]

在这种情况下,不是将解决方案分配给新列表,而是将输出分配给输入列表的切片。这里的操作顺序是什么允许这样做?为什么我们不会遇到通过常规for循环修改列表元素时提到的相同错误?

2 个答案:

答案 0 :(得分:2)

这里有两种不同的方法(__getitem____setitem__ 1 )。它与操作顺序没有任何关系,但是上下文允许python选择应该调用哪个函数。在后一种情况下,“切片”位于赋值语句的左侧,这是导致__setitem__被调用的原因。

这些方法可以执行您想要的任何操作 - 对于列表,使用切片对象调用时__getitem__会生成列表中特定部分的副本,并在调用时使用__setitem__切片会导致右侧插入该切片。

1 目前已弃用__setslice____getslice__方法

答案 1 :(得分:2)

语法someList[:]的含义略有不同,具体取决于它是否出现在作业的左侧。

someList[:]本身确实创建了一个(浅层)副本。

someList[:] = ...导致右侧的表达式替换列表的现有内容。没有创建副本。现有列表的内容已修改。

您也可以将其视为someList[:]始终意味着相同的事情,即“列表的内容”。 someList[:]本身会创建一个副本,因为它会为您提供列表的内容,而不是列表本身,因此它必须创建一个新列表来“保存”这些内容。分配给someList[:]会覆盖列表,因为它会替换现有列表的内容。