2016-02-11 3 views
0

У меня есть следующий списокОбъединить элементы по ключу в списке

some_list = [{'key': 'YOUNG', 'x': 22, 'y': 0.9}, 
      {'key': 'OLD', 'x': 45, 'y': 0.6}, 
      {'key': 'OLD', 'x': 40, 'y': 0.3}, 
      {'key': 'YOUNG', 'x': 25, 'y': 0.3}] 

, и я хотел бы изменить его на:

[{'key': 'YOUNG', 'values': [ {'x': 25, 'y': 0.3}, {'x': 22, 'y': 0.9} ]} 
{'key': 'OLD', 'values': [ {'x': 40, 'y': 0.3}, {'x': 45, 'y': 0.6} ]}] 

Добавлено несколько моих попыток

arr = [{'key': 'YOUNG', 'x': 22, 'y': 0.9}, 
     {'key': 'OLD', 'x': 45, 'y': 0.6}, 
     {'key': 'OLD', 'x': 40, 'y': 0.3}, 
     {'key': 'YOUNG', 'x': 25, 'y': 0.3}] 

all_keys = [] 
for item in arr: 
    all_keys.append(item['key']) 

all_keys = list(set(all_keys)) 

res = [[{ 
     'key': key, 
     'values': {'x': each['x'], 'y': each['y']} 
     } for each in arr if each['key'] == key] 
     for key in all_keys] 

print res  

Но результат неверен, он строит больше списков: [[{'values': {'y': 0.6, 'x': 45}, 'key': 'OLD'}, {'val ues ': {' y ': 0.3,' x ': 40},' key ':' OLD '}], [{' values ​​': {' y ': 0.9,' x ': 22},' key ' : 'YOUNG'}, {'values': {'y': 0.3, 'x': 25}, 'key': 'YOUNG'}]]

Спасибо.

+2

Опубликовать свой atte mpts .. –

+2

Stackoverflow не так, другие люди будут писать для вас код. Это так, что другие люди помогут вам понять, почему вы делаете что-то неправильно – ATLUS

+0

Pardon, я пришел из мира JavaScript, где я могу приблизиться к цели, итерируя список и переходя к другому. – Novitoll

ответ

3

петля должна быть такой:

res = [{ 'key': key, 
     'values': [{'x': each['x'], 'y': each['y']} 
        for each in arr if each['key'] == key] } 
     for key in all_keys] 
+0

прав, еще один список понял. Надеюсь, это выглядит больше pythonic :) Спасибо! – Novitoll

+0

Нет, я просто перевел ту, что была не в том месте. –

0

Другой попытка может использовать defaultdict - Он будет работать быстрее, если данные больше.

from collections import defaultdict 

data = defaultdict(list) 
some_list = [{'key': 'YOUNG', 'x': 22, 'y': 0.9}, 
      {'key': 'OLD', 'x': 45, 'y': 0.6}, 
      {'key': 'OLD', 'x': 40, 'y': 0.3}, 
      {'key': 'YOUNG', 'x': 25, 'y': 0.3}] 


for item in some_list: 
    vals = item.copy() 
    del vals['key'] 
    data[item['key']].append(vals) 

print [{'key':k,'values':v} for k,v in data.items()] 

Выход (словарь не заботится о заказе) -

[{'values': [{'y': 0.6, 'x': 45}, {'y': 0.3, 'x': 40}], 'key': 'OLD'}, {'values': [{'y': 0.9, 'x': 22}, {'y': 0.3, 'x': 25}], 'key': 'YOUNG'}] 
0
from itertools import * 
data = [{'key': 'YOUNG', 'x': 22, 'y': 0.9}, 
      {'key': 'OLD', 'x': 45, 'y': 0.6}, 
      {'key': 'OLD', 'x': 40, 'y': 0.3}, 
      {'key': 'YOUNG', 'x': 25, 'y': 0.3}] 
data = sorted(data, key=lambda x: x['key']) 
groups = [] 
uniquekeys = [] 

for k, v in groupby(data, lambda x: x['key']): 
    val_list = [] 
    for each_val in v: 
     val_list.append({ 'x' : each_val['x'], 'y': each_val['y']}) 
    groups.append(val_list) 
    uniquekeys.append(k) 

print uniquekeys 
print groups 
print zip(uniquekeys, groups) 

Вы получите свой выход в виде списка кортежей, где первый элемент является ключом, а второй из них является группа/список значений,

[('OLD', [{'y': 0.6, 'x': 45}, {'y': 0.3, 'x': 40}]), ('YOUNG', [{'y': 0.9, 'x': 22}, {'y': 0.3, 'x': 25}])] 
0
some_list = [{'key': 'YOUNG', 'x': 22, 'y': 0.9}, 
      {'key': 'OLD', 'x': 45, 'y': 0.6}, 
      {'key': 'OLD', 'x': 40, 'y': 0.3}, 
      {'key': 'YOUNG', 'x': 25, 'y': 0.3}] 

outDict = {} 

for dictionary in some_list: 
    key = dictionary['key'] 
    copyDict = dictionary.copy() #This leaves the original dict list unaltered 
    del copyDict['key'] 
    if key in outDict: 
     outDict[key].append(copyDict) 
    else: 
     outDict[key] = [copyDict] 

print(outDict) 
print(some_list) 
1

Использование промежуточный словарь вы можете сделать:

>>> temp_data = {} 
>>> for x in some_list: 
...  temp_data.setdefault(x['key'], []).append({k: x[k] for k in ['x', 'y']}) 
>>> [{'key': k, 'values': v} for k,v in temp_data.items()] 
[{'key': 'OLD', 'values': [{'x': 45, 'y': 0.6}, {'x': 40, 'y': 0.3}]}, 
{'key': 'YOUNG', 'values': [{'x': 22, 'y': 0.9}, {'x': 25, 'y': 0.3}]}] 

Хотя лично я бы просто оставить его в словарной форме:

>>> temp_data 
{'OLD': [{'x': 45, 'y': 0.6}, {'x': 40, 'y': 0.3}], 
'YOUNG': [{'x': 22, 'y': 0.9}, {'x': 25, 'y': 0.3}]} 
+0

Правильно, я замечаю, что люди из мира Python используют ключи как ключи :), но я использую слова типа «ключ», «значения», чтобы легко анализировать данные JS. Может быть, я должен передумать, чтобы быть более Pythonic :) Спасибо – Novitoll

+0

BTW для большого набора данных, ваш текущий подход довольно неэффективен O (n^2) против O (n) выше. Для небольших наборов данных не проблема. – AChampion

0

Здесь Перейти-

some_list = [{'key': 'YOUNG', 'x': 22, 'y': 0.9}, 
      {'key': 'OLD', 'x': 45, 'y': 0.6}, 
      {'key': 'OLD', 'x': 40, 'y': 0.3}, 
      {'key': 'YOUNG', 'x': 25, 'y': 0.3}] 

dict_young_vals = [] 
dict_old_vals = [] 
for dict_step in some_list: 
    temp_dict = {} 
    if (dict_step['key'] == 'YOUNG'): 
    for keys in dict_step.keys(): 
     if keys != 'key': 
     temp_dict[keys] = dict_step[keys] 
    if temp_dict != {}: 
     dict_young_vals.append(temp_dict) 
    if (dict_step['key'] == 'OLD'): 
    for keys in dict_step.keys(): 
     if keys != 'key': 
     temp_dict[keys] = dict_step[keys] 
    if temp_dict != {}: 
     dict_old_vals.append(temp_dict) 


dict_young = {'key':'YOUNG'} 
dict_young['values'] = dict_young_vals 
dict_old = {'key': 'OLD'} 
dict_old['values'] = dict_old_vals 
print(dict_young_vals) 
result_dict = [] 
result_dict.append(dict_young) 
result_dict.append(dict_old) 
print(result_dict) 
0
some_list = [{'key': 'YOUNG', 'x': 22, 'y': 0.9}, 
     {'key': 'OLD', 'x': 45, 'y': 0.6}, 
     {'key': 'OLD', 'x': 40, 'y': 0.3}, 
     {'key': 'YOUNG', 'x': 25, 'y': 0.3}] 

x=[] 

for i in some_list: 
    d={} 
    d["key"]=i["key"] 
    d["values"]=[{m:n for m,n in i.items() if m!="key"}] 
    if d["key"] not in [j["key"] for j in x]: 
     x.append(d) 
    else: 
     for k in x: 
      if k["key"]==d["key"]: 
       k["values"].append(d["values"][0]) 
print x 

Выход: [{'values': [{'y': 0.9, 'x': 22}, {'y': 0.3, 'x': 25}], 'key': 'YOUNG'}, {'values': [{'y': 0.6, 'x': 45}, {'y': 0.3, 'x': 40}], 'key': 'OLD'}]

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