2015-02-21 13 views
7

Ho due dizionari Python su cui sto cercando di sommare i valori. La risposta in: Is there any pythonic way to combine two dicts (adding values for keys that appear in both)? mi prende la maggior parte del modo. Tuttavia, ho casi in cui i valori netti possono essere zero o negativi ma voglio ancora i valori nel dizionario finale. Anche se i Contatori accettano valori negativi, emetteranno un valore solo se è maggiore di zero.combinando due dizionari Python in uno quando i valori netti non sono positivi

Esempio

from collections import Counter 
A = Counter({'a': 1, 'b': 2, 'c': -3, 'e': 5, 'f': 5}) 
B = Counter({'b': 3, 'c': 4, 'd': 5, 'e': -5, 'f': -6}) 
C = A + B 
print(C.items()) 

uscita: [('a', 1), ('c', 1), ('b', 5), ('d', 5)]

c = -3 + 4 = 1 è corretto in modo all'ingresso negativo non è un problema, ma e: 0 ef: -1 mancano dall'output

Come può Eseguo la sommatoria e ottieni tutti i valori in uscita?

+0

è necessario un ciclo su chiavi combinate ordinate univoche – Skaperen

risposta

4

ne dite qualcosa di simile:

dict((x, a.get(x, 0) + b.get(x, 0)) for x in set(a)|set(b)) 

esempio:

>>> a = {'a':1, 'b':2, 'c':-3, 'e':5, 'f': 5} 
>>> b = {'b':3, 'c':4, 'd':5, 'e':-5, 'f': -6} 
>>> 
>>> dict((x, a.get(x, 0) + b.get(x, 0)) for x in set(a)|set(b)) 
{'e': 0, 'a': 1, 'f': -1, 'd': 5, 'c': 1, 'b': 5} 
+0

Ciò non produce tuttavia un nuovo oggetto 'Counter()'. –

+2

Era necessario? Per quanto ho capito l'obiettivo era solo quello di aggiungere due dizionari insieme. Ma vero, non è così. – Roope

+0

in particolare con un contatore in quanto l'output non è un requisito. Alla fine, sto solo esportando i risultati finali in un file. Questo funziona. I contatori erano solo un mezzo per aggiungere il dizionario che ho trovato nel post di riferimento. Grazie – user3314562

7

Summing scende valori a 0 e inferiore, sì, come documentato:

Diverse operazioni matematiche sono previste combinando oggetti Contatore per produrre multiset (contatori che hanno conteggi superiori a zero). Addizione e sottrazione combinano i contatori aggiungendo o sottraendo i conteggi degli elementi corrispondenti. Intersezione e unione restituiscono il minimo e il massimo dei conteggi corrispondenti. Ogni operazione può accettare input con conteggi firmati, ma l'output escluderà i risultati con conteggi pari o inferiori a.

[...]

  • I metodi MultiSet sono progettati solo per i casi d'uso con valori positivi. Gli ingressi possono essere negativi o pari a zero, ma con vengono create solo le uscite con valori positivi. Non ci sono restrizioni di tipo, ma il tipo di valore deve supportare addizione, sottrazione e confronto.

Avrete bisogno di usare Counter.update() se si voleva mantenere i valori a 0 o inferiore. Dal momento che questa è un'operazione sul posto dovrete creare una copia qui:

>>> from collections import Counter 
>>> A = Counter({'a': 1, 'b': 2, 'c': -3, 'e': 5, 'f': 5}) 
>>> B = Counter({'b': 3, 'c': 4, 'd': 5, 'e': -5, 'f': -6}) 
>>> C = A.copy() 
>>> C.update(B) 
>>> C 
Counter({'b': 5, 'd': 5, 'a': 1, 'c': 1, 'e': 0, 'f': -1}) 

Se preservare A non era un obiettivo, è possibile solo aggiornare direttamente.

+0

Perché 'Counter()' si comporta in questo modo quando somma i conteggi negativi? mi sembra abbastanza inaspettato per me, non per il Python che conosco e ammiro ... –

+1

@Chris_Rands perché i contatori sono multipli; un set che gestisce sia l'appartenenza che un conteggio per quante volte fa parte del set. 0 (o inferiore) significa che non fa più parte del set, quindi viene rimosso. –

+0

Grazie, ha senso. Successivamente, in Python 3.5 e versioni successive è possibile utilizzare può combinare 'dict's con' {** A, ** B} ', ma ciò non funziona con' Counter (** A, ** B) ' –

Problemi correlati