2011-07-13 10 views

Odpowiedz

7

Oto jeden sposób:

result = dict(d2) 
for k in d1: 
    if k in result: 
     result[k] = (result[k] + d1[k])/2.0 
    else: 
     result[k] = d1[k] 
+0

Polecam przy użyciu 'd2.copy () 'zamiast' dykt (d2) '. Jest trochę szybszy (i szybszy dla dykta z kilkoma przedmiotami, do około dwa razy szybszy), a moim zdaniem bardziej oczywisty. –

+0

Chciałbym również pomnożyć przez 0.5 zamiast podziału. – psihodelia

2

Jeszcze innym sposobem:

result = dict(d1) 
for (k,v) in d2.items(): 
    result[k] = (result.get(k,v) + v)/2.0 
+0

+1: Bardzo podstępny! Musisz jednak poprawić nazwy zmiennych. – phant0m

+0

dobrze nakrapiane i naprawione. dzięki. – Frank

6

To będzie działać na dowolną liczbę słowników:

dicts = ({"a": 5},{"b": 2, "a": 10}, {"a": 15, "b": 4}) 
keys = set() 
averaged = {} 
for d in dicts: 
    keys.update(d.keys()) 
for key in keys: 
    values = [d[key] for d in dicts if key in d] 
    averaged[key] = float(sum(values))/len(values) 
print averaged 
# {'a': 10.0, 'b': 3.0} 

Aktualizacja: @mhyfritz pokazał sposób, w jaki można zmniejszyć 3 linie do jednej!

dicts = ({"a": 5},{"b": 2, "a": 10}, {"a": 15, "b": 4}) 
averaged = {} 
keys = set().union(*dicts) 
for key in keys: 
    values = [d[key] for d in dicts if key in d] 
    averaged[key] = float(sum(values))/len(values) 
print averaged 
+2

+1 dla uogólnionego rozwiązania! –

+1

+1. Na marginesie możesz napisać 'keys = set(). Union (* dicts)'. Wykorzystuje to fakt, że 'set'' 'dict' (only) zawiera' _dy__ 'dict'. – mhyfritz

+0

@mhyfritz: Heh, to jest miłe! - BTW: czy @user działa również w odpowiedziach? – phant0m

3

Twoje pytanie było najbardziej "pythonowe".

Myślę, że w przypadku takiego problemu, sposób Pythonic jest bardzo jasny. Istnieje wiele sposobów wdrożenia rozwiązania tego problemu! Jeśli naprawdę masz tylko 2 dykty, to rozwiązania, które zakładają to, są świetne, ponieważ są znacznie prostsze (i łatwiejsze do odczytania i utrzymania). Jednak często dobrym pomysłem jest posiadanie ogólnego rozwiązania, ponieważ oznacza to, że nie musisz duplikować większości logiki w innych przypadkach, gdy masz na przykład 3 słowniki.

Jako uzupełnienie, odpowiedź phant0m jest dobra, ponieważ wykorzystuje wiele funkcji Pythona, aby umożliwić odczytanie rozwiązania. Widzimy listowych:

[d[key] for d in dicts if key in d] 

Korzystając z Pythona bardzo przydatny set typu:

keys = set() 
keys.update(d.keys()) 

i ogólnie, dobre wykorzystanie metod typu Pythona i globalnych:

d.keys() 
keys.update(...) 
keys.update 
len(values) 

myślenia i Wdrożenie algorytmu rozwiązania tego problemu to jedno, ale uczynienie go tak eleganckim i czytelnym dzięki wykorzystaniu siły języka jest tym, co większość ludzi uznałaby za "Python".

(użyłbym rozwiązanie phant0m za)

+0

+1: Dzięki za miłą analizę :) – phant0m

+0

@ phant0m dzięki za świetne rozwiązanie :) – adamnfish

+0

+1, teraz analizuj moje: P –

0

licznikiem a niektóre Generatory są przydatne w tej sytuacji

Case ogólne:

>>> d1 = { 'apples': 2, 'oranges':5 } 
>>> d2 = { 'apples': 1, 'bananas': 3 } 
>>> all_d=[d1,d2] 
>>> from collections import Counter 
>>> counts=Counter(sum((d.keys() for d in all_d),[])) 
>>> counts 
Counter({'apples': 2, 'oranges': 1, 'bananas': 1}) 
>>> s=lambda k: sum((d.get(k,0) for d in all_d)) 
>>> result_set=dict(((k,1.0*s(k)/counts[k]) for k in counts.keys())) 
>>> result_set 
{'apples': 1.5, 'oranges': 5.0, 'bananas': 3.0} 
0
d1 = { 'apples': 2, 'oranges':5 } 
d2 = { 'apples': 1, 'bananas': 3, 'oranges':0 } 
dicts = [d1, d2] 

result_dict = {} 

for dict in dicts: 
    for key, value in dict.iteritems(): 
     if key in result_dict: 
      result_dict[key].append(value) 
     else: 
      result_dict[key] = [value] 

for key, values in result_dict.iteritems(): 
    result_dict[key] = float(sum(result_dict[key]))/len(result_dict[key]) 

print result_dict 
Powiązane problemy