Python:Collections.Counter与defaultdict(int)

Python:Collections.Counter与defaultdict(int),python,dictionary,Python,Dictionary,假设我有一些如下所示的数据 Lucy = 1 Bob = 5 Jim = 40 Susan = 6 Lucy = 2 Bob = 30 Harold = 6 我要组合1)删除重复键,2)添加这些重复键的值。这意味着我将获得键/值: Lucy = 3 Bob = 35 Jim = 40 Susan = 6 Harold = 6 (从集合中)使用计数器或默认dict更好吗?计数器和默认dict(int)在这里都可以正常工作,但它们之间没有什么区别: 计数器支持在计算机上执行的大多数操作。所以,

假设我有一些如下所示的数据

Lucy = 1
Bob = 5
Jim = 40
Susan = 6
Lucy = 2
Bob = 30
Harold = 6
我要组合1)删除重复键,2)添加这些重复键的值。这意味着我将获得键/值:

Lucy = 3
Bob = 35
Jim = 40
Susan = 6
Harold = 6

(从集合中)使用计数器或默认dict更好吗?

计数器和默认dict(int)在这里都可以正常工作,但它们之间没有什么区别:

  • 计数器
    支持在计算机上执行的大多数操作。所以,若你们想使用这些操作,那个么就去计数器

  • 当您查询缺少的密钥时,
    计数器
    不会向dict添加新密钥。因此,如果您的查询中包含可能不在dict中的键,那么最好使用
    计数器

例如:

>>> c = Counter()
>>> d = defaultdict(int)
>>> c[0], d[1]
(0, 0)
>>> c
Counter()
>>> d
defaultdict(<type 'int'>, {1: 0})
>>> c = Counter('aaaaaaaaabbbbbbbcc')
>>> c.most_common()
[('a', 9), ('b', 7), ('c', 2)]
>>> c.most_common(2)          #return 2 most common items and their counts
[('a', 9), ('b', 7)]
>>> c = Counter({'a':5, 'b':3})
>>> list(c.elements())
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b']
  • 计数器
    还允许您从计数器对象创建元素列表
例如:

>>> c = Counter()
>>> d = defaultdict(int)
>>> c[0], d[1]
(0, 0)
>>> c
Counter()
>>> d
defaultdict(<type 'int'>, {1: 0})
>>> c = Counter('aaaaaaaaabbbbbbbcc')
>>> c.most_common()
[('a', 9), ('b', 7), ('c', 2)]
>>> c.most_common(2)          #return 2 most common items and their counts
[('a', 9), ('b', 7)]
>>> c = Counter({'a':5, 'b':3})
>>> list(c.elements())
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b']

因此,根据您想要对结果dict执行的操作,您可以在
计数器
默认dict(int)
之间进行选择,我支持使用
默认dict(int)
对计数进行求和,例如在本例中,以及使用
计数器()
对列表元素进行计数。在您的情况下,以下是最干净的解决方案:

name_count = [
    ("Lucy", 1),
    ("Bob", 5),
    ("Jim", 40),
    ("Susan", 6),
    ("Lucy", 2),
    ("Bob", 30),
    ("Harold", 6)
]

aggregate_counts = defaultdict(int)
for name, count in name_count:
    aggregate_counts[name] += count
defaultdict(int)
似乎工作得更快

In [1]: from collections import Counter, defaultdict

In [2]: def test_counter():
   ...:     c = Counter()
   ...:     for i in range(10000):
   ...:         c[i] += 1
   ...:

In [3]: def test_defaultdict():
   ...:     d = defaultdict(int)
   ...:     for i in range(10000):
   ...:         d[i] += 1
   ...:

In [4]: %timeit test_counter()
5.28 ms ± 1.2 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [5]: %timeit test_defaultdict()
2.31 ms ± 68.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

这两种方法都有效吗?然后掷硬币。这就是说,
collections.Counter
似乎是用来对重复元素的列表进行计数的。谢谢您的帮助!在这里发现了另一个很好的问题——从Python3.2开始,这个问题可能不成立,请参见:@TalJerome我在Python3.6中测试了这个问题。为什么不将
range()
对象直接传递到
Counter()