Python collections.Counter() 运行时

问题描述 投票:0回答:2

我刚刚遇到一个问题,我需要列出一个列表,例如

l = [1, 2, 3, 4]
,进入 dic,例如
{1: 1, 2: 1, 3: 1, 4: 1}
。我只是想知道我是否应该使用
collections.Counter()
或者自己编写一个循环来执行此操作。内置方法比自己写循环更快吗?

python counter
2个回答
5
投票

您可以随时使用 timeit 模块来

测试
是否更快。在 Python 3 中,
Counter
对象具有 C 性能改进,并且速度确实非常快:

>>> from timeit import timeit
>>> import random, string
>>> from collections import Counter, defaultdict
>>> def count_manually(it):
...     res = defaultdict(int)
...     for el in it:
...         res[el] += 1
...     return res
...
>>> test_data = [random.choice(string.printable) for _ in range(10000)]
>>> timeit('count_manually(test_data)', 'from __main__ import test_data, count_manually', number=2000)
1.4321454349992564

>>> timeit('Counter(test_data)', 'from __main__ import test_data, Counter', number=2000)
0.776072466003825

这里

Counter()
快了2倍。

也就是说,除非您计算的是代码的性能关键部分,否则请重点关注可读性和可维护性,在这方面,

Counter()
胜过编写您自己的代码。

除此之外,

Counter()
对象提供了字典之上的功能:它们可以被视为多重集(您可以对计数器求和或相减,并生成并集或交集),并且它们可以有效地为您提供前N个元素按计数。


1
投票

这取决于可读性v/s效率。让我们先看看这两个实现。我将使用它作为示例运行的列表:

my_list = [1, 2, 3, 4, 4, 5, 4, 3, 2]

使用

collections.Counter()

from collections import Counter
d = Counter(my_list)

使用

collections.defaultdict()
创建我自己的计数器:

from collections import defaultdict
d = defaultdict(int)
for i in [1, 2, 3, 4, 4, 5, 4, 3, 2]: 
    d[i] += 1

如您所见,

collections.Counter()
更具可读性

让我们看看使用

timeit
的效率:

  • Python 2.7中:

    mquadri$ python -m "timeit" -c "from collections import defaultdict" "d=defaultdict(int)" "for i in [1, 2, 3, 4, 4, 5, 4, 3, 2]: d[i] += 1"
    100000 loops, best of 3: 2.95 usec per loop
    
    mquadri$ python -m "timeit" -c "from collections import Counter" "Counter([1, 2, 3, 4, 4, 5, 4, 3, 2])"
    100000 loops, best of 3: 6.5 usec per loop
    

    collection.Counter()
    实现比自己的代码慢2倍

  • Python 3中:

    mquadri$ python3 -m "timeit" -c "from collections import defaultdict" "d=defaultdict(int)" "for i in [1, 2, 3, 4, 4, 5, 4, 3, 2]: d[i] += 1"
    100000 loops, best of 3: 3.1 usec per loop
    
    mquadri$ python3 -m "timeit" -c "from collections import Counter" "Counter([1, 2, 3, 4, 4, 5, 4, 3, 2])"
    100000 loops, best of 3: 5.57 usec per loop
    

    collections.Counter()
    比自己的代码快两倍

© www.soinside.com 2019 - 2024. All rights reserved.