2015-06-10 15 views
6

jestem stosunkowo nowych do Python 2.7, i nie może dowiedzieć się, co następuje pomimo poszukiwania obszernie na StackOverflow:Merge wartości samego klucza, w liście dicts

Mam list z dict S I wa połączyć, gdy klucz jest taki sam i dodać określone wartości (w przykładzie 'price').

Wejście:

[{'id1': 'a', 'price': '2', 'color': 'green'}, {'id1': 'b', 'price': '5', 'color': 'red'}, {'id1': 'a', 'price': '2', 'color': 'green'}] 

Oczekiwany:

[{'id1': 'a', 'price': '4', 'color': 'green'}, {'id1': 'b', 'price': '5', 'color': 'red'}] 

Odpowiedz

4

sam pomysł jako swoje pytanie przed edit.

>>> data = [{'id1': 'a', 'price': '2', 'color': 'green'}, 
...   {'id1': 'b', 'price': '5', 'color': 'red'}, 
...   {'id1': 'a', 'price': '2', 'color': 'green'}] 

Construct tymczasowy słownika i gromadzą się w nim wartości

>>> temp = {} 
>>> for d in data: 
...  if d['id1'] not in temp: 
...   temp[d['id1']] = {} 
...  temp_d = temp[d['id1']] 
...  temp_d['price'] = temp_d.get('price', 0) + int(d['price']) 
...  temp_d.setdefault('colors', set()).add(d['color']) 
... 
>>> temp 
{'a': {'colors': {'green'}, 'price': 4}, 'b': {'colors': {'red'}, 'price': 5}} 

Następnie za pomocą listowych i słownik zrozumieniem, zrekonstruować listę słowników.

>>> [{'id1': k, 'price': v['price'], 'colors': v['colors']} for k, v in temp.items()] 
[{'id1': 'a', 'colors': {'green'}, 'price': 4}, {'id1': 'b', 'colors': {'red'}, 'price': 5}] 

>>> data = [{'id1': 'a', 'price': '2'}, {'id1': 'b', 'price': '5'}, 
...   {'id1': 'a', 'price': '2'}] 

Tworzenie tymczasowej słownika, gdzie możemy accummulate sumę cen przed ich identyfikatory,

>>> temp = {} 
>>> for d in data: 
...  temp[d['id1']] = temp.get(d['id1'], 0) + int(d['price']) 
... 
>>> temp 
{'a': 4, 'b': 5} 

Tutaj staramy się uzyskać wartość d['id1'] z temp i jeśli to nie znaleziono, zostanie zwrócone 0. Następnie dodajemy price z bieżącego słownika i przechowujemy wynik z powrotem w temp w stosunku do bieżącego id1.

Następnie zrekonstruować listę słowników, z list comprehension i słownik zrozumienia, jak to

>>> [{'id1': k, 'price': temp[k]} for k in temp] 
[{'price': 4, 'id1': 'a'}, {'price': 5, 'id1': 'b'}] 
+0

Very nice. Jedynym problemem jest to, że pierwszy dict ma inną wartość, kolor, w jednym z wystąpień {'id1': "a", "cena": "2", "kolor": "czerwony"} Jak zachować to w ostatni dyktat? – DauleDK

+0

@DauleDK Czy kolor będzie taki sam dla danego "id1" we wszystkich słownikach? Na przykład, jeśli "id1" to "a" i czy kolor będzie zawsze "zielony"? – thefourtheye

+0

Nie zawsze, czy możliwe jest połączenie wartości? – DauleDK

0

To nie jest tak ładny jak @thefourtheye ale wydaje się działać dla mnie:

di = [{'id1': 'a', 'price': '2', 'color': 'green'}, {'id1': 'b', 'price': '5', 'color': 'red'}, {'id1': 'a', 'price': '2', 'color': 'green'}] 

# Make a dict to hold new values! 
newvals = {} 

for d in di: 
    for key, value in d.iteritems(): 
     if value.isdigit(): 
      if value in newvals: 
       newvals[value] += int(value) 
      else: 
       newvals[value] = int(value) 
     else: 
      if value not in newvals: 
       newvals[value] = value 

for d in di: 
    for nkey, nvalue in d.iteritems(): 
     d[nkey] = newvals[nvalue] 

# Make a unique list of dicts 
print {v['id1']:v for v in di}.values() 

>>>[{'color': 'green', 'price': 4, 'id1': 'a'}, {'color': 'red', 'price': 5, 'id1': 'b'}] 
Powiązane problemy