【问题标题】:Get complement (opposite) of list slice获取列表切片的补码(相反)
【发布时间】:2017-02-08 18:37:45
【问题描述】:

是否有语法可以获取不在给定切片内的列表元素? 给定切片 [1:4] 很容易得到这些元素:

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

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

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

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

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

【问题讨论】:

  • 这可能不是你想要的,所以我把它放在评论而不是答案中,但是如果你想修改原始列表,你可以分配到切片中。例如l[1:4] = []
  • 你也可以使用numpy数组。
  • 如果您不介意操作列表,您可以del l[1:4],但它不会返回。
  • Invert slice in python的可能重复

标签: python list slice


【解决方案1】:

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

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

否则,您最初的建议将是最简洁的方式。没有办法使用单个 slice 语句获得与列表切片相反的结果。

【讨论】:

    【解决方案2】:

    显然,最好的解决方案是创建一个类来封装使用'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]
    

    【讨论】:

    • 很明显。除非我将'c' 替换为'<-- whatever is not, repeat NOT, in this range'。为了可读性。清楚地。我的眼睛受伤了。
    【解决方案3】:
    [x for i, x in enumerate(l) if i not in range(1, 4)]
    

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

    【讨论】:

      【解决方案4】:

      我一直在为这个问题寻找一些解决方案,以便正确处理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]
      

      据我所知,它也可以处理所有极端情况,包括steps,无论是正数还是负数,以及重复值。

      我想把它写成一个生成器,但是检查所有极端情况下的所有参数的正/负/None 值让我很恼火。 当然,原则上这是可能的。

      【讨论】:

        【解决方案5】:

        你可以在循环中使用列表推导

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

        【讨论】:

        • 这不起作用有几个原因。一个无效的语法。第二,如果你的列表是[1, 1, 1, 1, 1]
        • 抱歉我忘记写了。
        • 是的。这在上述列表条件下不起作用
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-09
        • 1970-01-01
        • 1970-01-01
        • 2011-08-18
        • 1970-01-01
        相关资源
        最近更新 更多