【问题标题】:Create range without certain numbers创建没有特定数字的范围
【发布时间】:2014-10-11 16:08:42
【问题描述】:

我想从0 ... n 创建一个范围x,而列表y 中没有任何数字。我该怎么做?

例如:

n = 10
y = [3, 7, 8]
x = # Do Something

应该给出输出:

x = [0, 1, 2, 4, 5, 6, 9]

一种天真的方法是连接多个范围,每个范围跨越一组数字,这些数字已与y 中的数字相交。但是,我不确定在 Python 中最简单的语法是什么。

【问题讨论】:

  • 问:你试过什么?问:你考虑过 Python set 操作吗?

标签: python range


【解决方案1】:

您可以使用列表推导来过滤从 0n 的范围:range(n) 生成从 0n - 1 的列表(或者,在 Python 3 中,生成器对象)(包括两者结束):

x = [i for i in range(n) if i not in y]

这会从范围中过滤掉y 中的所有数字。

您还可以将其变成一个生成器(您只能迭代一次,但对于(非常)大的n 会更快),方法是将[ 替换为( 并将] 替换为) .此外,在 Python 2 中,您可以使用 xrange 而不是 range 来避免一次将整个范围加载到内存中。此外,特别是如果 y 是一个大列表,您可以先将其转换为 set 以使用 O(1) 成员资格检查而不是 O(n)listtuple 对象上。这样的版本可能看起来像

s = set(y)
x = (i for i in range(n) if i not in s)

【讨论】:

  • 最好将y 转换成一个集合以避免昂贵的in 运算符用于列表。
  • 那是什么?有人说very relevant post about in operations吗?
  • 在本例中,您可以利用 set(y) 将被构建一次并在每个成员测试中重复使用这一事实,因此构建集合的成本与范围。 n 越大,首先构建集合就越有意义。 (链接的问题是关于进行 single 成员资格测试。)
  • 哎呀,修复了那个东西(也就是一直在重建集合)
【解决方案2】:

hlt 的答案很理想,但我会很快提出另一种使用 set 操作的方法。

n = 10
y = [3, 7, 8]
x = set(range(n)) - set(y)

x 将是一个 set 对象。如果你确实需要x 成为list,你可以写x = list(x)

请注意,Python 中的集合的顺序不能保证是特定的。如果需要排序,记得排序。

【讨论】:

  • 虽然这看起来很不错,但它可能(不会)保留排序。
【解决方案3】:

除了上面的答案,这是我使用 lambda 函数的答案:

x = filter(lambda x: x not in y,range(n))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    • 2015-07-02
    • 2016-08-12
    • 1970-01-01
    • 2020-01-24
    相关资源
    最近更新 更多