частота элементов в списке словарей Python - PullRequest
8 голосов
/ 29 июня 2009

Хорошо, у меня есть список диктов:

[{'name': 'johnny', 'surname': 'smith', 'age': 53},
 {'name': 'johnny', 'surname': 'ryan', 'age': 13},
 {'name': 'jakob', 'surname': 'smith', 'age': 27},
 {'name': 'aaron', 'surname': 'specter', 'age': 22},
 {'name': 'max', 'surname': 'headroom', 'age': 108},
]

и я хочу «частоту» пунктов в каждом столбце. Так что для этого я бы получил что-то вроде:

{'name': {'johnny': 2, 'jakob': 1, 'aaron': 1, 'max': 1}, 
'surname': {'smith': 2, 'ryan': 1, 'specter': 1, 'headroom': 1}, 
'age': {53:1, 13:1, 27: 1. 22:1, 108:1}}

Какие-нибудь модули, которые могут делать такие вещи?

Ответы [ 4 ]

13 голосов
/ 29 июня 2009

collections.defaultdict из стандартной библиотеки на помощь:

from collections import defaultdict

LofD = [{'name': 'johnny', 'surname': 'smith', 'age': 53},
 {'name': 'johnny', 'surname': 'ryan', 'age': 13},
 {'name': 'jakob', 'surname': 'smith', 'age': 27},
 {'name': 'aaron', 'surname': 'specter', 'age': 22},
 {'name': 'max', 'surname': 'headroom', 'age': 108},
]

def counters():
  return defaultdict(int)

def freqs(LofD):
  r = defaultdict(counters)
  for d in LofD:
    for k, v in d.items():
      r[k][v] += 1
  return dict((k, dict(v)) for k, v in r.items())

print freqs(LofD)

излучает

{'age': {27: 1, 108: 1, 53: 1, 22: 1, 13: 1}, 'surname': {'headroom': 1, 'smith': 2, 'specter': 1, 'ryan': 1}, 'name': {'jakob': 1, 'max': 1, 'aaron': 1, 'johnny': 2}}

по желанию (порядок ключей отдельно, конечно - это не имеет значения в диктовке).

2 голосов
/ 29 июня 2009

Новое в Python 3.1: collections.Counter класс:

mydict=[{'name': 'johnny', 'surname': 'smith', 'age': 53},
 {'name': 'johnny', 'surname': 'ryan', 'age': 13},
 {'name': 'jakob', 'surname': 'smith', 'age': 27},
 {'name': 'aaron', 'surname': 'specter', 'age': 22},
 {'name': 'max', 'surname': 'headroom', 'age': 108},
]

import collections
newdict = {}

for key in mydict[0].keys():
    l = [value[key] for value in mydict]
    newdict[key] = dict(collections.Counter(l))

print(newdict)

выходы:

{'age': {27: 1, 108: 1, 53: 1, 22: 1, 13: 1}, 
'surname': {'headroom': 1, 'smith': 2, 'specter': 1, 'ryan': 1}, 
'name': {'jakob': 1, 'max': 1, 'aaron': 1, 'johnny': 2}}
2 голосов
/ 29 июня 2009
items = [{'name': 'johnny', 'surname': 'smith', 'age': 53},  {'name': 'johnny', 'surname': 'ryan', 'age': 13},  {'name': 'jakob', 'surname': 'smith', 'age': 27},  {'name': 'aaron', 'surname': 'specter', 'age': 22},  {'name': 'max', 'surname': 'headroom', 'age': 108}]

global_dict = {}

for item in items:
    for key, value in item.items():
        if not global_dict.has_key(key):
            global_dict[key] = {}

        if not global_dict[key].has_key(value):
            global_dict[key][value] = 0

        global_dict[key][value] += 1

print global_dict

Самое простое и проверенное решение.

1 голос
/ 29 июня 2009

Это

from collections import defaultdict
fq = { 'name': defaultdict(int), 'surname': defaultdict(int), 'age': defaultdict(int) }
for row in listOfDicts:
    for field in fq:
       fq[field][row[field]] += 1
print fq
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...