2009-06-28 8 views
8

Ok, donc j'ai une liste de dicts:fréquence élément dans une liste python de dictionnaires

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

et je veux la « fréquence » des éléments de chaque colonne. Donc, pour ce que je voudrais obtenir quelque chose comme:

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

Des modules là-bas qui peuvent faire des choses comme ça?

Répondre

13

collections.defaultdict de la bibliothèque standard à la rescousse:

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) 

émet

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

comme vous le souhaitez (ordre de clés en dehors, bien sûr - il est hors de propos dans un dict).

1

Ceci?

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 

solution et effectivement testé Simplest.

+0

C'est probablement que je l'aurais finalement fait, n'a jamais entendu parler de collections.defaultdict. – dochead

+0

Comment simplifier la duplication de la logique "if not has_key" que regroupe collections.defaultdict? C'est ce que j'aurais fait en 1.5.2 (avant d'ajouter l'idiome plus simple et plus rapide 'if key in global_dict' dans 2.0) mais" compatible avec les versions archaïques "n'équivaut pas à" simple ";-). –

+0

Le plus simple pour les débutants :) – zinovii

2

Nouveau en Python 3.1: La classe 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) 

sorties:

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