2013-11-09 2 views
15

Предположим, у меня есть некоторые данные, которые выглядят следующим образом.Python: Collections.Counter vs defaultdict (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 

было бы лучше использовать (из коллекции) счетчик или словарь по умолчанию для этого?

+2

Оба работают? Затем переверните монету. Тем не менее, кажется, что 'collections.Counter' есть для подсчета списка с повторяющимися элементами. – millimoose

+1

Составьте оба варианта и посмотрите, какой из них вам больше нравится. – NPE

ответ

23

Оба Counter и defaultdict(int) могут нормально работать здесь, но есть некоторые различия между ними:

  • Counter поддерживает большинство операций, которые вы можете сделать на multiset. Итак, если вы хотите использовать эту операцию, перейдите в Counter.

  • Counter не будет добавлять новые ключи к dict, когда вы запрашиваете отсутствующие ключи. Итак, если ваши запросы содержат ключи, которые могут отсутствовать в dict, лучше используйте Counter.

Пример:

>>> c = Counter() 
>>> d = defaultdict(int) 
>>> c[0], d[1] 
(0, 0) 
>>> c 
Counter() 
>>> d 
defaultdict(<type 'int'>, {1: 0}) 

Пример:

  • Counter также имеет метод most_common, который позволяет сортировать элементы по их подсчета. Чтобы получить то же самое в defaultdict, вам нужно будет использовать sorted.

Пример:

>>> 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)] 
  • Counter также позволяет создать список элементов объекта счетчика.

Пример:

>>> c = Counter({'a':5, 'b':3}) 
>>> list(c.elements()) 
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b'] 

Так, в зависимости от того, что вы хотите сделать с полученной Dict вы можете выбрать между Counter и defaultdict(int).

+1

Я бы также добавил, что счетчик имеет встроенную сортировку по значениям с помощью 'most_common()' –

+0

@KevinStone. –

+0

Спасибо за помощь! Нашел еще один хороший вопрос --http: //stackoverflow.com/questions/10654499/removing-duplicate-keys-from-python-dictionary-but-summing-the-values – covariance

0

Я поддерживаю использование defaultdict(int) для подсчета сумм, например, в данном случае, и Counter() для подсчета элементов списка. В вашем случае самым чистым решением будет следующее:

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 
Смежные вопросы