Объединение элементов в 2D-списке на основе общих первых элементов - PullRequest
1 голос
/ 06 марта 2020

Учитывая следующий список:

lst = [[3,5],[3,10],[3,15],[3,102],[5,21],[5,23],[5,50]]

Я хочу получить следующее [[3,5,10,15,102], [5,21,23,50]]

Обратите внимание, что список отсортирован в порядке возрастания на основе значения первого элемента.

Какой самый эффективный способ сделать это? Вот о чем я думал:

Шаг 1. Создайте список с уникальными первыми элементами. (т.е. в данном случае 3 и 5)

first_elements = [] #initialize empty list to which we will append all first elements
for i in range(len(lst)):
    first_elements.append(lst[i][0])
first_elements = list(set(first_elements)) #Filter out the unique first elements
    first_elements = [3,5]

Шаг 2: Фильтр lst на основе первого элемента. Добавьте их в новый список.

new_merged_list = [] # create new list to append to
for i in range(len(first_elements)): 
    first_element_to_filter_by = first_elements[i]
    filtered_2d_list           = [i for i in lst if i[0] == first_element_to_filter_by]
    new_merged_list.append([first_element_to_filter_by])

    for j in range(len(filtered_2d_list)):
        (new_merged_list[i]).append(filtered_2d_list[j][1])    

Это дает мне правильный ответ, как показано ниже.

new_merged_list = [[3, 5, 10, 15, 102], [5, 21, 23, 50]]

Мой вопрос - есть ли более эффективный способ сделать это? Я не знаю, насколько хорошо это будет масштабироваться до списка, который (например) 100000 x 2.

Оцените помощь!

Ответы [ 4 ]

10 голосов
/ 06 марта 2020

Вы можете использовать defaultdict здесь. Это будет работать, даже если ваш lst не отсортирован.

from collections import defaultdict
new=defaultdict(list)
lst = [[3,5],[3,10],[3,15],[3,102],[5,21],[5,23],[5,50]]

for k,v in lst:
    new[k].append(v)

new=[[k]+v for k,v in new.items()]
# [[3, 5, 10, 15, 102], [5, 21, 23, 50]]
# Or 
new=[[k,*v] for k,v in new.items()]
# [[3, 5, 10, 15, 102], [5, 21, 23, 50]]
2 голосов
/ 06 марта 2020

За один проход.

lst = [[3,5],[3,10],[3,15],[3,102],[5,21],[5,23],[5,50]]

    current = None
    ret = []
    for i in lst:
        if i[0] == current:
            ret[-1].append(i[1])
        else:
            current = i[0]
            ret.append([current])
            ret[-1].append(i[1])

# [[3, 5, 10, 15, 102], [5, 21, 23, 50]]
2 голосов
/ 06 марта 2020
# seems to work - assuming the initial sorting as stated

result = []

prv_first = None
for sub_lst in lst:
    first = sub_lst[0]
    if first != prv_first:
        prv_first = first
        cur_list = [] + sub_lst
        result.append(cur_list)
    else:
        cur_list.extend(sub_lst[1:])
2 голосов
/ 06 марта 2020

Вы можете сделать что-то вроде этого (без импорта модуля)

first_elements = list(set([item[0] for item in lst]))
result = [[elem] for elem in first_elems]
for sublist in lst:
    result[first_elems.index(sublist[0])].append(sublist[1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...