2014-01-29 18 views
7

Ich habe N Wörterbücher, die die gleichen Schlüssel enthalten, mit Werten, die ganze Zahlen sind. Ich möchte diese in einem einzigen Wörterbuch basierend auf dem Maximalwert zusammenführen. Zur Zeit habe ich so etwas wie diese:Mehrere Wörterbücher bedingt zusammenfügen

max_dict = {} 
for dict in original_dict_list: 
    for key, val in dict.iteritems(): 
     if key not in max_dict or max_dict[key] < val: 
      max_dict[key] = val 

Gibt es eine bessere (oder mehr „pythonic“) Art und Weise, dies zu tun?

Antwort

7

Verwenden collection.Counter() objects sondern sie unterstützen nativ zählt 'Verschmelzung':

from collections import Counter 

max_dict = Counter() 
for d in original_dict_list: 
    max_dict |= Counter(d) 

oder sogar:

from collections import Counter 
from operator import or_ 

max_dict = reduce(or_, map(Counter, original_dict_list)) 

Counter Objekte sind Multi-Sets (auch genannt 'Taschen' manchmal). Der Operator | führt eine Union auf zwei Zählern durch und speichert die maximale Anzahl für einen bestimmten Schlüssel.

Eine Counter ist auch eine direkte Unterklasse von dict, so dass Sie es (fast) wie jedes andere Wörterbuch behandeln können.

Demo:

>>> from collections import Counter 
>>> from operator import or_ 
>>> original_dict_list = [{'foo': 3, 'bar': 10}, {'foo': 42, 'spam': 20}, {'bar': 5, 'ham': 10}] 
>>> reduce(or_, map(Counter, original_dict_list)) 
Counter({'foo': 42, 'spam': 20, 'bar': 10, 'ham': 10}) 
2

Unter der Annahme, nicht alle Wörterbücher enthalten alle Schlüssel:

keys = set(k for x in original_dict_list for k in x) 
max_dict = {k:max([x[k] for x in original_dict_list if k in x]) for k in keys} 
+1

In diesem speziellen Fall könnten Sie 'x [k]' statt 'x.get (k, -1) ', weil die Wörterbücher alle dieselben Schlüssel verwenden. Wenn nicht, würde ich vorschlagen, Ihr innerstes Listenverständnis durch '[x [k] für x in original_dict_list wenn k in x]' zu ersetzen – Kevin

0
max_dict = { k:max([v]+[ _dict[k] for _dict in original_dict_list[1:] ]) 
      for k,v in original_dict_list[0].items() } 
Verwandte Themen