2009-06-28 4 views
8

Ok, więc mam listę dicts:częstotliwość pozycja na liście Pythona słowników

[{'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}, 
] 

i chcę „częstotliwości” z pozycji w każdej kolumnie. Więc otrzymam coś takiego:

{'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}} 

Jakieś moduły, które mogą robić takie rzeczy?

Odpowiedz

13

collections.defaultdict z biblioteki do ratowania:

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) 

emituje

{'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}} 

dowolny (rzędu przycisków z wyjątkiem, oczywiście - to jest bez znaczenia w dict).

1

To?

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 
2
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 

Najprostszym rozwiązaniem i faktycznie testowany.

+0

To chyba jak bym w końcu to zrobił, nigdy nie słyszał o collections.defaultdict. – dochead

+0

Jak to jest łatwiej powielać logikę "if not has_key", którą collections.defaultdict ucieleśnia? Tak postąpiłbym w wersji 1.5.2 (zanim dodaliśmy prostszy i szybszy idiom 'if key not in global_dict' w 2.0), ale" kompatybilny z archaicznymi wersjami "nie oznacza" prostego ";-). –

+0

Najprostszy dla początkujących :) – zinovii

2

nowego w Pythonie 3.1: collections.Counter klasa:

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) 

wyjścia:

{'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}}