【问题标题】:What is best practice to use generators for counting purposes使用生成器进行计数的最佳实践是什么
【发布时间】:2015-12-12 04:30:34
【问题描述】:

假设我有一个类似的列表:

my_list = range(10)

我想计算列表中有多少个偶数。请注意,我对这些值不感兴趣,我只想要它们的数量。所以我可以:

len( [0 for i in my_list if i % 2 == 0] ) # Method 1
len( [i for i in my_list if i % 2 == 0] ) # Method 2
len( [_ for i in my_list if i % 2 == 0] ) # Method 3

从速度或内存的角度来看,上述方法是否比其他方法更好?

其实我什至不需要构建列表,但我不想:

counter = 0
for item in my_list:
   if item % 2 == 0:
      counter += 1

那么,哪一个是使用生成器计数的好方法?

PS:在我的例子中,列表有更多的内存项,这就是我想尽可能优化的原因。

【问题讨论】:

  • 推荐:学习如何使用timeit 并自己衡量这些结果。如果你使用 IPython 和它的内置 %timeit 魔法会更容易......
  • @CorleyBrigman 感谢您的推荐。我使用并喜欢 %timeit。但是,这里的问题主要是调查内存效率。我正在寻找另一种在不生成列表本身的情况下计算项目的方法。
  • 确实如此。另外,也许相关:stackoverflow.com/questions/393053/length-of-generator-output ...顺便说一句,既然你提到了生成器,那么你正在使用 python 3?
  • @CorleyBrigman 不。 Python 2.7 4eva。

标签: python count generator


【解决方案1】:

以上都不用。使用sum() 和生成器表达式:

sum(i % 2 == 0 for i in mylist)

在 Python 中,bool 布尔类型是int 的子类,True 的整数值为1False0,因此您可以将一系列True 相加和False 结果。

sum()-with-generator 表达式一次只需要在内存中保留一个布尔值,不需要生成中间列表并保留它来计算长度。

或者,坚持过滤和求和 1 文字:

sum(1 for i in mylist if i % 2 == 0)

这导致需要添加的对象更少。

【讨论】:

  • @TessellatingHeckler:那些10 microseconds 加起来,不是吗?
  • @TessellatingHeckler 计算奇数是解释我的问题的一个展示案例。我实际上对找出一个数字是否偶数的最快方法并不感兴趣。无论如何,谢谢。
  • @TessellatingHeckler:但是,对于i = 2,表达式~(i & 1) 产生-1,而对于i = 1,您得到-2。这真的会影响结果,因为我们将这些 -2 和 -1 相加,而不是 0 或 1。您必须改用 1 - (i & 1),或者将总和除以 -2..
  • @MartijnPieters eeeee,哎呀。和我一起回到绘图交互解释器。
  • 在阅读了另一个问题之后,看起来sum(1 for i in mylist if i %2 == 0) 更快一些(对于 python 2.7 中的 xrange(1000),我得到 112 uS 的布尔值总和,77uS 的总和过滤 1s。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-16
  • 2018-03-13
  • 1970-01-01
相关资源
最近更新 更多