得到列表切片的补充(相反)

时间:2017-02-08 18:37:46

标签: python list slice

是否有语法来获取列表中的元素不在给定切片中? 鉴于切片[1:4],很容易得到这些元素:

>>> l = [1,2,3,4,5]
>>> l[1:4]
[2, 3, 4]

如果我想要列表的其余部分,我可以这样做:

>>> l[:1] + l[4:]
[1, 5]

有没有更简洁的方法来做到这一点?我意识到我可能太穷了,因为这已经非常简洁了。

编辑:我认为这不是Invert slice in python的副本,因为我不想修改原始列表。

5 个答案:

答案 0 :(得分:1)

如果要就地修改列表,可以删除切片:

>>> l = [1, 2, 3, 4, 5]
>>> del l[1:4]
>>> l
[1, 5]

否则你最初的建议将是最简洁的方式。没有办法使用单个切片语句来获得列表切片的反面。

答案 1 :(得分:0)

显然,创建一个类来封装使用'c'作为步长值时发生的一些神奇行为的最佳解决方案。清楚。

class SuperList(list):
    def __getitem__(self, val):
        if type(val) is slice and val.step == 'c':
            copy = self[:]
            copy[val.start:val.stop] = []
            return copy

        return super(SuperList, self).__getitem__(val)


l = SuperList([1,2,3,4,5])
print l[1:4:'c'] # [1, 5]

答案 2 :(得分:0)

[x for i, x in enumerate(l) if i not in range(1, 4)]

哪个不够简洁。所以你的问题的答案是否定的,你不能更简洁地做到这一点。

答案 3 :(得分:0)

我正在寻找此问题的解决方案,该解决方案也应允许正确处理step参数。 所提出的解决方案均未真正可行,因此我最终编写了自己的解决方案:

def complement_slice(items, slice_):
    to_exclude = set(range(len(items))[slice_])
    step = slice_.step if slice_.step else 1
    result = [
        item for i, item in enumerate(items) if i not in to_exclude]
    if step > 0:
        return result
    else:
        return result[::-1]

ll = [x + 1 for x in range(5)]
# [1, 2, 3, 4, 5]
sl = slice(1, 4)

ll[sl]
# [2, 3, 4]

complement_slice(ll, sl)
# [1, 5]

据我所知,它也处理所有极端情况,包括step(包括正数和负数)以及重复值。

我想将其编写为一个生成器,但是由于检查所有拐角处所有参数的正/负/ None值而感到恼火。 原则上,当然可以。

答案 4 :(得分:-2)

您可以使用带有循环的列表理解

l = [i for i in l if i not in l[1:4]]