Я программирую на Python и у меня есть список списков

a=[[1234,32.5,'John',1114],[1234,16.3,'John',1115],[1235,25.3,'John',1116],
  [1239,16.3,'Lisa',1117]]

Как я могу объединить списки аналогичного элемента в субиндекс [0] и удалить список, который содержит наименьший элемент индекса [3]?

Ожидаемый выход:

a=[[1234,48.8,'John',1115],[1235,25.3,'John',1116],[1239,16.3,'Lisa',1117]]

Поскольку

 a[1][3] > a[0][3] (1116 > 1115) 

a[0][1] будет добавлен в a[1][1], а a[0] будет полностью удален.

Я планирую использовать это для списка из десяти тысяч списков.

РЕДАКТИРОВАТЬ:

Я сделал:

old=[[1234,32.5,'John',1114],[1234,16.3,'John',1115],[1235,25.3,'John',1116],[1239,16.3,'Lisa',1117]]

memory=old[0]

new=[]

for x, t in enumerate(old):
    if t==memory:
        new.append([t[0],memory[1]+t[1],t[2],t[3]])
        memory=t

Но это не сработает в списках, если существует более двух списков, которые похожи по индексу [0], код следует запускать снова и снова, в зависимости от количества похожих элементов. В приложении мой список списков будет иметь сотни похожих элементов в определенном индексе.

0
Michael Esporlas 26 Фев 2018 в 07:54

3 ответа

Лучший ответ

Что вам действительно нужно, так это сгруппировать ваши данные по общим ключам. itertools.groupby создан для этого, и вы можно использовать operator.itemgetter для группировки по ключу элементы каждого подсписка.

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

from itertools import groupby
from operator import itemgetter

def merge(data):
    out_data = []
    for _, group in groupby(data, key=itemgetter(0, 2)):
        key_num, to_sum, key_name, to_max = next(group)
        for _, sum_val, _, max_val in group:
            to_sum += sum_val
            to_max = max(to_max, max_val)
        out_data.append([key_num, to_sum, key_name, to_max])
    return out_data

< Сильного > Demo

>>> a = [[1234,32.5,'John',1114],
         [1234,16.3,'John',1115], 
         [1235,25.3,'John',1116], 
         [1239,16.3,'Lisa',1117]]

>>> merge(a)
[[1234, 48.8, 'John', 1115],
 [1235, 25.3, 'John', 1116],
 [1239, 16.3, 'Lisa', 1117]]

Также стоит отметить, что если у вас есть много операций для применения к табличным данным, подобным этому, вы можете заглянуть в Панды библиотека. Используя Pandas, можно получить краткое решение вашей проблемы.

import pandas as pd

def pd_merge(data):
    df = pd.DataFrame(data)    
    return (df.groupby((0, 2), as_index=False)
              .agg({1: 'sum', 3: 'max'})
              .sort_index(1))
1
miradulo 26 Фев 2018 в 05:53

Ниже мое решение, кажется, что может обрабатывать элементы, которые более 2:

from collections import defaultdict

a=[[1234,32.5,'John',1114], [1234,32.5,'John',1113],[1234,16.3,'John',1115],[1235,25.3,'John',1116],  [1239,16.3,'Lisa',1117]]

def merge_list(data):
    total_dic = defaultdict(list)
    new_data = []
    for elem in a:
        total_dic[elem[0]].append(elem)

    for dic_elem in total_dic:
        total_dic[dic_elem].sort(key=lambda x: x[3], reverse=False)
        if(len(total_dic[dic_elem]) > 1):
            new_data.append(total_dic[dic_elem][1:])
        else:
            new_data.append(total_dic[dic_elem][0])
    return new_data

print(merge_list(a))

[[[1234, 32.5, 'John', 1114], [1234, 16.3, 'John', 1115]], [1235, 25.3, 'John', 1116], [1239, 16.3, 'Lisa', 1117]]
0
Alex Lee 26 Фев 2018 в 06:03

Спасибо всем, мне удалось ответить на мою проблему с помощью itertools groupby

Вот мой рабочий прототип:

from itertools import groupby
from operator import itemgetter


def merge(data):
    out_data = []
    for key, group in groupby(data, key=itemgetter('name','time')):
        id_temp = 0
        dep_temp=0

        dict_temp={}
        for t in group:
            dict_temp=t
            if t["deposit_id"] < id_temp:
                dict_temp['deposit_id']=id_temp
            else:
                id_temp=dict_temp['deposit_id']
            dep_temp+=dict_temp['deposit']
        dict_temp['deposit'], dict_temp['deposit_id'] = dep_temp, id_temp
        out_data.append(dict_temp)
    return out_data

a = [{'name':'John','time':1234,'deposit':16.7,'deposit_id':1115},
 {'name':'John','time':1234,'deposit':24.3,'deposit_id':1116},
 {'name':'John','time':1234,'deposit':65.3,'deposit_id':1117},
 {'name':'John','time':1235,'deposit':95.3,'deposit_id':1118},
 {'name':'Lisa','time':1235,'deposit':95.3,'deposit_id':1119}]

b=merge(a)

for t in b:
    print t

Выход

{'deposit_id': 1117, 'deposit': 106.3, 'name': 'John', 'time': 1234}
{'deposit_id': 1118, 'deposit': 95.3, 'name': 'John', 'time': 1235}
{'deposit_id': 1119, 'deposit': 95.3, 'name': 'Lisa', 'time': 1235}
0
Michael Esporlas 26 Фев 2018 в 10:01