Объединить словарь списков на основе значения - PullRequest
0 голосов
/ 04 июня 2019

У меня есть список словарей, и я пытаюсь объединить некоторые элементы словаря, если идентификатор совпадает.

Например, можно найти фрагмент набора данных.здесь:

[... , {'time': 1554283273.0824468, 'quaternion': [0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707], 'id': 13762}
{'time': 1554283273.1220775, 'quaternion': [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095], 'id': 13762}
{'time': 1554283273.1620576, 'quaternion': [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217], 'id': 13762}, ...]

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

[..., {'time':(1554283273.0824468, 1554283273.1220775, 1554283273.1620576), 'quaternion': ([0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707], [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095], [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217]), 'id': 13762}, ...]

Ответы [ 5 ]

0 голосов
/ 04 июня 2019

Вот еще один скрипт:

_list = [{'time': 1554283273.0824468, 'quaternion': [0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707], 'id': 13762}
,{'time': 1554283273.1220775, 'quaternion': [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095], 'id': 13762}
,{'time': 1554283273.1620576, 'quaternion': [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217], 'id': 13762}]
_dict = {} 
tmp, qmp  =[], []     #initialize the lists
for d in _list:
    t, q = d['time'], d['quaternion']    #get the values of time and quaternion
    tmp.append(t)      #add the value to list t
    qmp.extend(q)       #extend means add the items of the list instead of the list itself
_dict['time'] = tmp     #assign the collected values to time
_dict['quaternion'] = qmp  #assign the collected values to quaternion
_dict
0 голосов
/ 04 июня 2019

Вот универсальное решение. Функция:

def group_dict_by_key(list_of_dicts, key):
    res = {}
    for item in list_of_dicts:
        if item[key] not in res:
            res[item[key]] = {key: item[key]}
        temp = res[item[key]]
        for k, v in item.items():
            if k == key:
                continue
            elif k in temp:
                temp[k] += (v,)
            else:
                temp[k] = (v,)
    return list(res.values())

Входные данные:

d = [{'time': 1554283273.0824468, 'quaternion': [0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707], 'id': 13762},
{'time': 1554283273.1220775, 'quaternion': [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095], 'id': 13762},
{'time': 1554283273.1620576, 'quaternion': [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217], 'id': 13762},
{'time': 1554283273.0824468, 'quaternion': [0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707], 'id': 13763},
{'time': 1554283273.1220775, 'quaternion': [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095], 'id': 13763},
{'time': 1554283273.1620576, 'quaternion': [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217], 'id': 13763}]

Usage:

final = group_dict_by_key(d, 'id')

Выход:

[
    {
        'id': 13762,
        'time': (1554283273.0824468, 1554283273.1220775, 1554283273.1620576),
        'quaternion': (
            [0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707],
            [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095],
            [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217]
        )
    }, {
        'id': 13763,
        'time': (1554283273.0824468, 1554283273.1220775, 1554283273.1620576),
        'quaternion': (
            [0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707],
            [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095],
            [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217]
        )
    }
]
0 голосов
/ 04 июня 2019

Вот, пожалуйста:

l = [{'time': 1554283273.0824468, 'quaternion': [0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707], 'id': 13762},
{'time': 1554283273.1220775, 'quaternion': [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095], 'id': 13762},
{'time': 1554283273.1620576, 'quaternion': [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217], 'id': 13762}]

all_id = set(dict_['id'] for dict_ in l) # All unique 'id' in the list
new_l = []
for id_ in all_id:
    all_time = [dict_['time'] for dict_ in l if dict_['id'] == id_]
    all_q = [dict_['quaternion'] for dict_ in l if dict_['id'] == id_]
    new_l.append({'time' : all_time, 'quaternion' : all_q, 'id' : id_})

Выход :

# new_l becomes :
[{'quaternion': [[0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707], [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095], [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217]], 'id': 13762, 'time': [1554283273.0824468, 1554283273.1220775, 1554283273.1620576]}]
0 голосов
/ 04 июня 2019

Вы можете сделать это по умолчанию, чтобы накопить меньший словарь для каждого «идентификатора».Чтобы получить список словарей в качестве вывода, вы можете взять .values ​​() из этого по умолчанию dict:

dicts =[ {'time': 1554283273.0824468, 'quaternion': [0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707], 'id': 13762},
         {'time': 1554283273.1220775, 'quaternion': [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095], 'id': 13762},
         {'time': 1554283273.1620576, 'quaternion': [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217], 'id': 13762}
       ]

from collections import defaultdict
combined = defaultdict(dict)
for d in dicts:
    combined[d["id"]]["id"] = d["id"]
    combined[d["id"]].setdefault("time",[]).append(d["time"])
    combined[d["id"]].setdefault("quaternion",[]).extend(d["quaternion"])
combined = list(combined.values())
print(combined)

# [{'id': 13762, 'time': [1554283273.0824468, 1554283273.1220775, 1554283273.1620576], 'quaternion': [0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707, -0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095, 0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217]}]
0 голосов
/ 04 июня 2019

Использование collections.defaultdict:

from collections import defaultdict

lst = [{'time': 1554283273.0824468, 'quaternion': [0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707], 'id': 13762},
       {'time': 1554283273.1220775, 'quaternion': [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095], 'id': 13762},
       {'time': 1554283273.1620576, 'quaternion': [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217], 'id': 13762}]

res = []
for x in lst:
    d = defaultdict(tuple)
    d['time'] += (x['time'],)
    d['quaternion'] += (x['quaternion'],)
    d['id'] = x['id']
    res.append(d)

print(res)
# [{'time':(1554283273.0824468, 1554283273.1220775, 1554283273.1620576), 
#   'quaternion': ([0.17855453309035293, 0.005453680566358193, -0.9834562739434834, -0.0300381977216707], [-0.9705062538096711, -0.029642658768302424, -0.23913505674039495, -0.007304021853201095], [0.836337807006856, 0.02554468467443435, -0.5473637151080412, -0.016718404199258217]),
#   'id': 13762}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...