在Python中切片列表混乱

时间:2012-12-13 18:15:25

标签: python list slice del

好吧,我是Python的新手,有些事情让我对切片列表感到烦恼。当我从这段代码中切割[1]和[3]时,为什么我得到[1,3,4]?

z = [1, 2, 3, 4, 5]
del z[1], z[3]
print z

我认为我会回来[1,3,5]因为它[2]和[4]被删除了。

if - > [1,2,3,4,5]
是 - > [0,1,2,3,4]

我的逻辑在哪里搞砸了?

5 个答案:

答案 0 :(得分:6)

第一次删除会更改列表索引,因此下一个删除不是之前的位置... 简化

>>> a = [1, 2, 3]
>>> del a[0] # should delete 1
>>> a
[2, 3]
>>> del a[1] # This use to be the index for 2, but now `3` is at this index
>>> a
[2]

答案 1 :(得分:3)

删除一次完成一个。第一个删除将所有后续元素向左移动一个位置:

In [3]: z = [1, 2, 3, 4, 5]

In [5]: del z[1]

In [6]: z
Out[6]: [1, 3, 4, 5]

In [7]: z[3]
Out[7]: 5

如果您将索引从最大到最小排列,这不会发生,因为没有删除会更改任何相关索引:

In [18]: z = [1, 2, 3, 4, 5]

In [19]: del z[3], z[1]

In [20]: z
Out[20]: [1, 3, 5]

答案 2 :(得分:1)

当您进行删除时,它们会一次发生一次,因此每次删除都会使向右值在一个索引上向左移动。

z = [1, 2, 3, 4, 5]

del z[1] # [1, X, 3, 4, 5] --> [1, 3, 4, 5]

del z[3] # [1, 3, 4, X] --> [1, 3, 4]

您应该采取哪些措施来保存订单,这是为了将您的删除从最大到最小的索引排序,以便不会转移任何内容,

del z[3]; del z[1]

更好的做法是立即进行所有删除操作以完全避免问题:

z = [1, 2, 3, 4, 5]
del z[1::2]
# returns [1, 3, 5]

答案 3 :(得分:0)

其他人已经提到你的代码有什么问题,我可以真正理解你打算做什么的推理

如果你想要删除第二和第四个元素而不关心转移列表,你应该在一个bredth中做,可能的解决方案是通过List COmprehension

def inplace_del(it, rng): 
    return [e for i, e in enumerate(it) if i not in set(rng)]
inplace_del(z,(2,3))
[1, 2, 5]
y = xrange(1,6)
inplace_del(y,(2,3))
[1, 2, 5]

更好的解决方案是使用itertools

>>> from itertools import count, compress
>>> def in_del(it, rng):
    rng = set(rng)
    holes = (e not in rng for e in count(0))
    return compress(it, holes)

>>> list(in_del(z,(2,3)))
[1, 2, 5]
>>> list(in_del(y,(2,3)))
[1, 2, 5]
>>> 

答案 4 :(得分:0)

您看到此行为的原因是del z[1], z[3]完全等同于在单独的行中del z[1]del z[3]。因此,第一个del语句将移动后续元素,z[3]成为最后一个元素(5):

>>> def del_test():
...     del z[1], z[3]
...
>>> def del_test2():
...     del z[1]
...     del z[3]
...
>>> del_test.__code__.co_code == del_test2.__code__.co_code
True