2013-08-06 2 views
1

Я долго пробовал этот мозг, и теперь передаю его более мудрым. У меня есть список dicts (длина списка может варьироваться от 1 до 100). Эти списки имеют в основном дубликаты с одним или двумя значениями. Клавиши для всех dict всегда остаются неизменными. Примером может быть, как показано ниже:Как слить dicts из списка dicts в python?

myList = [ 
{"k1" : "v11", "k2" : "v21", "k3" : "v31", "k4" : "v41"}, 
{"k1" : "v12", "k2" : "v22", "k3" : "", "k4" : ""}, 
{"k1" : "v11", "k2" : "v21", "k3" : "", "k4" : "v41"}, 
{"k1" : "v11", "k2" : "v21", "k3" : "v31", "k4" : ""}, 
{"k1" : "v12", "k2" : "v22", "k3" : "v32", "k4" : ""} 
] 

Теперь я знаю, что MyList [0], MyList [2] и MyList [3] такие же, как и большинство их текущих значений одинаковы. Аналогично, myList [1] и myList [4] совпадают.

То, что я хочу, чтобы реализовать функцию слияния (MyList), которая даст выход так:

newList = [ 
{"k1" : "v11", "k2" : "v21", "k3" : "v31", "k4" : "v41"}, 
{"k1" : "v12", "k2" : "v22", "k3" : "v32", "k4" : ""} 
] 

Спасибо большое заранее за вашу помощь.

Приветствие, Paritosh

+4

Так почему '«k3»: «" игнорируется? Каковы правила слияния, * точно *? –

+0

Возможный дубликат [Как объединить список dicts в один dict?] (Http://stackoverflow.com/questions/3494906/how-do-i-merge-a-list-of-dicts-into- a-single-dict) – Marcin

+0

Правила слияния: если два dicts имеют максимальное количество повторяющихся значений (для соответствующих ключей), объедините их. И это не возможный дубликат упомянутого вопроса, потому что я не хочу объединять все диктофоны в один диктант, дикты с максимально возможными общими значениями должны сливаться. Если все dicts имеют разные значения, они не должны сливаться. – Paritosh

ответ

2

Я бы собрать все значения в defaultdict с set значений, а затем разархивировать значения обратно в отдельные словари; от некоторых экспериментов я предполагаю, что вы хотите игнорировать пустые значения и только положить их обратно в, чтобы компенсировать выходной словарь:

from collections import defaultdict 
from itertools import izip_longest 

values = defaultdict(set) 
for map in myList: 
    for key, value in map.iteritems(): 
     if value: 
      values[key].add(value) 

keys = list(values) 
newList = [dict(zip(keys, row)) for row in izip_longest(*(sorted(v) for v in values.itervalues()), fillvalue='')] 

Теперь мы получаем:

[{'k1': 'v11', 'k2': 'v21', 'k3': 'v31', 'k4': 'v41'}, 
{'k1': 'v12', 'k2': 'v22', 'k3': 'v32', 'k4': ''}] 
+0

Я проверил решение. Он прекрасно работает для данных значений. Однако, если мы усложняем ввод немного больше, он терпит неудачу. Например, 'myList = [ {" k1 ":" v11 "," k2 ":" v21 "," k3 ":" v31 "," k4 ":" v41 "}, {" k1 ":" v12 "," k2 ":" v22 "," k3 ":" "," k4 ":" "}, {" k1 ":" v11 "," k2 ":" v21 "," k3 ":" ", "k4": "v41"}, {"k1": "v11", "k2": "v21", "k3": "v31", "k4": ""}, {"k1": " v12 "," k2 ":" v22 "," k3 ":" v32 "," k4 ":" "}, {" k1 ":" v12 "," k2 ":" v23 "," k3 ":" v33 "," k4 ":" v43 "} ]'. Я ожидаю вывод с myList [5] как отдельный dict, поскольку максимальные значения не являются обманами. – Paritosh

Смежные вопросы