2015-06-10 3 views
6

Я сравнительно новым для Python 2.7, и не могу понять следующее, несмотря на поиски экстенсивно на StackOverflow:Объединить значения одного и того же ключа, в списке dicts

У меня есть list из dict S I wan't для объединения, когда ключ тот же, и добавьте определенные значения (в примере 'price').

Вход:

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

Ожидаемое:

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

ответ

4

Та же самая идея, как ваш вопрос до редактирования.

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

Построить временный словарь и накапливают значения в нем

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

Затем, используя список понимание и словарь понимание, восстановить список словарей.

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

Создания временного словаря, где мы можем accummulate суммы цен против их идентификаторов

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

Здесь мы попытаемся получить значение d['id1'] от temp и если он не найден, 0 будет возвращено. Затем мы добавим price из текущего словаря и сохраним результат в temp против текущего id1.

Затем восстановить список словарей, с list comprehension и словаря понимания, как этот

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

Очень приятно. Единственная проблема заключается в том, что первый dict фактически имеет другое значение, цвет, в одном из случаев {'id1': 'a', 'price': '2', 'color': 'red'} Как сохранить это в окончательный dict? – DauleDK

+0

@DauleDK Будет ли цвет одинаковым для данного 'id1' во всех словарях? Например, если 'id1' является' a' и будет ли цвет «зеленым» всегда? – thefourtheye

+0

Не всегда, может быть, возможно соединить значения тогда? – DauleDK

0

Это не так хорошо, как @thefourtheye, но, кажется, работает для меня:

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