生成反序列

时间:2014-02-06 21:56:32

标签: python range

我有一个序列

range(0,50,3)

[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48]

这是我想要生成的序列(每次不包括第3个元素),但能够在第n个数字处开始和结束:

[1, 2, 4, 5, 7, 8, ...]

6 个答案:

答案 0 :(得分:3)

这个怎么样:

def inv_range(start, stop, step):
  for val in range(start, stop):
    if (val - start) % step != 0:
      yield val

print list(inv_range(0,50,3))

打印

[1, 2, 4, 5, 7, 8, 10, 11, ...

P.S。如果您使用的是Python 2,请将range()替换为xrange()以获得恒定内存解决方案。

答案 1 :(得分:2)

构建要排除set个数字,并在整个范围的列表推导中对其进行测试:

>>> checkset = set(range(0, 50, 3))
>>> [x for x in range(50) if x not in checkset]
[1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47, 49]

将列表转换为集合并不重要,但是当您正在进行比较时,可以加快查找速度

答案 2 :(得分:2)

对于这个特例:

[x for x in range(50) if x % 3]

答案 3 :(得分:1)

不是最有效的解决方案,但快速且易于理解

excludes = range(0,50,3)
others = [x for x in range(50) if x not in excludes]

答案 4 :(得分:1)

怎么样

r = range(0,50)
del r[::3]
print r
# [1, 2, 4, 5, 7, 8, ...]

答案 5 :(得分:0)

对于这样的问题,有人问“我怎样才能稍微修改Python内置函数的行为来做X?”我建议查看所述函数的PyPy实现,然后修改它。

在这种情况下,这里是PyPy的range() and xrange() implementations

我意识到这不是简单的出路,但你可能会在这个过程中学到新的东西。

基本上看起来你想要的是range()的变体,它返回通常被跳过的值(即range()的补码)。使用range()的实现作为起点,看起来不会花费太多工作。