【问题标题】:range(len(list)) or enumerate(list)? [duplicate]范围(len(list))还是枚举(list)? [复制]
【发布时间】:2012-08-12 23:25:43
【问题描述】:

可能重复:
Only index needed: enumerate or (x)range?

哪些会被认为更好/更清晰/更快/更“Pythonic”?我不关心列表L的内容,只关心它有多长。

a = [f(n) for n, _ in enumerate(L)]

a = [f(n) for n in range(len(L))]

如果有任何区别,函数f 也使用len(list)

【问题讨论】:

  • 你用的是什么版本的python?

标签: python python-2.7 iteration list-comprehension


【解决方案1】:

一些快速的计时运行似乎使使用range() 的第二个选项比enumerate() 略有优势:

timeit a = [f(n) for n, _ in enumerate(mlist)]
10000 loops, best of 3: 118 us per loop

timeit a = [f(n) for n in range(len(mlist))]
10000 loops, best of 3: 102 us per loop

使用xrange() (Python v2.7.2) 只是为了好玩

timeit a = [f(n) for n in xrange(len(mlist))]
10000 loops, best of 3: 99 us per loop

我希望首先使用可读代码,然后使用xrange()(如果可用)(即 Pre-Python v 3.x),然后是range()enumerate()

【讨论】:

  • 当您想要重复访问其索引处的列表项时,枚举会更快。当您只需要索引列表时,使用 len() 和 range/xrange 会更快。
【解决方案2】:

(x)range 解决方案更快,因为它的开销更少,所以我会使用它。

在 Python 2.x 中,使用 xrange 而不是 range,因为 xrange 使用的内存更少,因为它不会创建临时列表。在 Python 3.x 中,只有 range,这是内存较少的版本。

因此,在 Python 2.x 中,迭代 range(n) 临时使用 O(n) 内存,而迭代 xrange(n) 使用 O(1) 暂时记忆。两者的运行时间都是O(n)

【讨论】:

  • xrange 是生成器对象吗? documentation 没有提到那个词,尽管你的描述听起来很像。
  • 它不是一个生成器对象(即在其主体中带有yield 的纯Python 代码),但它等价于用C 实现。它有一个.next() 方法返回下一个值或引发 StopIteration,for 循环重复调用此.next() 方法。 (如果你觉得我的答案有用,请投票。)
  • nitpick: range 不会创建一个临时列表,它会创建一个临时范围。因此,在 xrange 上使用范围时,只有恒定的时间开销。
  • @PeterZeller:range 返回的内容(列表或范围对象)取决于 Python 版本(2.x 或 3.x)。这正确地反映在答案中。您的语句 range 不会创建临时列表 对于 Python 2.x 不正确。我已经用 O(...) 扩展了内存和时间的答案。
【解决方案3】:

我会说,由于您没有使用 enumerate 函数中的“_”属性,因此请使用 range,因为这样更具可读性。

【讨论】:

    【解决方案4】:

    假设您使用的是 Python 2.x,如果您使用 len(),则应使用 xrange(),因为它会避免创建范围内的数字列表。

    在这种情况下,我会选择len(),因为您使用的是索引,而不是列表中的项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-06
      • 1970-01-01
      • 2012-08-07
      • 2014-01-27
      • 1970-01-01
      • 2022-11-30
      • 2021-10-08
      • 1970-01-01
      相关资源
      最近更新 更多