小编典典

需要一种快速的方法来单次计算和求和一个迭代

python

谁能帮我?我正在尝试提出一种计算方法

>>> sum_widths = sum(col.width for col in cols if not col.hide)

并计算此总和中的项目数,而不必进行两次以上的传递cols

似乎令人难以置信,但是在扫描了std-
lib(内置函数,itertools,functools等)后,我什至找不到一个可以计算可迭代对象数的函数。我发现了这个函数itertools.count,听起来像我想要的,但实际上它只是一个虚假命名的range函数。

经过一番思考,我想出了以下内容(它很简单,缺少库函数可能是可以原谅的,除了它的晦涩):

>>> visable_col_count = sum(col is col for col in cols if not col.hide)

但是,使用这两个函数需要两次迭代,这给我带来了错误的认识。

作为替代,以下功能可以实现我想要的功能:

>>> def count_and_sum(iter):
>>>     count = sum = 0
>>>     for item in iter:
>>>         count += 1
>>>         sum += item
>>>     return count, sum

问题在于,它花费的时间timeit是生成器表达式形式之和的100倍(根据)。

如果有人能拿出一个简单的单行代码满足我的要求,请告诉我(使用Python 3.3)。

编辑1

伙计们,这里有很多很棒的主意。感谢所有答复。我将花一些时间来消化所有这些答案,但是我将并且我将尝试选择一个进行检查。

编辑2

我对两个拙劣的建议(count_and_sum函数和2个单独的sum函数)重复了计时,并发现我原来的计时已过时,这可能是由于后台运行了自动计划的备份过程。

我还按时给出了答案中给出的大多数出色建议,所有建议都使用相同的模型。分析这些问题的答案一直是我相当的教育:新的用途dequeenumeratereduce与第一次countaccumulate。谢谢大家!

这是使用我开发的用于显示的软件的结果(来自我的慢速上网本):

┌───────────────────────────────────────────────────────┐
│                 Count and Sum Timing                  │
├──────────────────────────┬───────────┬────────────────┤
│          Method          │Time (usec)│Time (% of base)│
├──────────────────────────┼───────────┼────────────────┤
│count_and_sum (base)      │        7.2│            100%│
│Two sums                  │        7.5│            104%│
│deque enumerate accumulate│        7.3│            101%│
│max enumerate accumulate  │        7.3│            101%│
│reduce                    │        7.4│            103%│
│count sum                 │        7.3│            101%│
└──────────────────────────┴───────────┴────────────────┘

(我没有把复杂和折叠方法视作太模糊了,但还是要感谢。)

由于所有这些方法之间的时间差异很小,因此我决定使用该count_and_sum函数(带有显式for循环)作为最易读,显式和简单的函数(Python
Zen),并且它碰巧是最快的!

我希望我能接受这些令人惊奇的答案之一是正确的,但是尽管或多或少有些晦涩,但它们都同样好,所以我只是在投票给所有人,并接受我自己的答案是正确的(count_and_sum函数),因为这就是我使用的。

“应该有一种-最好只有一种-明显的方式来做到这一点”是什么意思?


阅读 181

收藏
2021-01-20

共1个答案

小编典典

感谢您提供所有出色的答案,但我决定使用原来的count_and_sum函数,如下所示:

>>> cc, cs = count_and_sum(c.width for c in cols if not c.hide)

正如我对原始问题的修改中所解释的那样,事实证明这是最快,最易读的解决方案。

2021-01-20