gpt4 book ai didi

python - 在 Python 中求和 Counter 对象的有效方法

转载 作者:行者123 更新时间:2023-12-04 00:12:53 29 4
gpt4 key购买 nike

是否有更有效的方法或库可以更快地添加 Counter 对象?

到目前为止,我正在使用以下代码,我需要比它更快的代码:

cnt = sum([Counter(objects) for objects in object_list], Counter())

最佳答案

不要制作大量的临时 Counter,只需制作一个,然后让它计数所有内容:

from collections import Counter
from itertools import chain

cnt = Counter(chain.from_iterable(object_list))

从较小的输入中创建一堆单独的 Counter 成本很高,并且会剥夺 Counter 用于计算输入迭代的 C 加速器提供的一些性能优势你。使用 sum 将它们组合成 Schlemiel the Painter's algorithm ,因为它使大量的临时 Counter 大小逐渐增加(工作最终大致是 O(m * n) 其中 n 是计数的项目总数,m 是它们被拆分的对象数)。对扁平化的输入迭代进行一次计数可以将工作降低到 O(n)

将您的可迭代对象扁平化为单个输入流并一次性计数一次极大地减少了运行时间,尤其是对于大量较小的对象。

像这样使用 chain.from_iterable 相当于:

cnt = Counter(item for object in object_list for item in object)

但是将工作推送到 CPython 引用解释器上的 C 层;如果 object_list 的内容也都是用 C 实现的内置类型,那么当你使用 chain.from_iterable 时根本不会执行任何字节码,移除一个 大量的解释器开销。

如果你必须有一堆 Counter,至少要避免 Schlemiel the Painter 的算法,方法是对累加器 Counter 进行就地更新。您可以以一种丑陋的方式将其单线化(这仍然会产生临时的 Counter,但至少它不会使每次都丢弃的逐渐更大的临时对象)与:

cnt = functools.reduce(operator.iadd, map(Counter, object_list), Counter())

或使其更具可读性(并避免任何额外的临时性):

cnt = Counter()
for obj in object_list:
cnt.update(obj) # cnt += Counter(obj) works, but involves unnecessary temporary

关于python - 在 Python 中求和 Counter 对象的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67171978/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com