Найти кортеж в списке с тем же первым элементом и вернуть другой список - PullRequest
1 голос
/ 31 марта 2019

У меня есть такой список в Python:

[('a', 'b'), ('a', 'c'),('d','f')]

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

[('a', 'b', 'c'),('d','f')]

Ответы [ 3 ]

1 голос
/ 31 марта 2019

Вот один из способов сделать это. Для эффективности мы строим dict с первым значением в качестве ключа. Мы сохраняем значения в том порядке, в котором они отображаются (и кортежи в их первоначальном порядке, если вы используете Python> = 3.7 - в противном случае вам придется использовать collections.OrderedDict)

def join_by_first(sequences):
    out = {}
    for seq in sequences:
        try:
            out[seq[0]].extend(seq[1:])
        except KeyError:
            out[seq[0]] = list(seq)
    return [tuple(values) for values in out.values()]

join_by_first([('a', 'b'), ('a', 'c'),('d','f')])
# [('a', 'b', 'c'), ('d', 'f')]
0 голосов
/ 31 марта 2019

Мне кажется, самое простое решение - создать словарь, в котором:

  • ключи - первые элементы в кортежах
  • значения - это списки, объединяющие все вторые элементы из кортежей

Получив это, мы можем построить список вывода:

from collections import defaultdict

def merge(pairs):
    mapping = defaultdict(list)
    for k, v in pairs:
        mapping[k].append(v)
    return [(k, *v) for k, v in mapping.items()]

pairs = [('a', 'b'), ('a', 'c'),('d','f')]
print(merge(pairs))

Это выводит:

[('a', 'b', 'c'), ('d', 'f')]

Это решение находится в O (n) , поскольку мы повторяем только два раза для каждого элемента из pairs.

0 голосов
/ 31 марта 2019

Вы не можете редактировать tuples - они неизменны.Вы можете использовать lists и затем преобразовать все обратно в tuples:

data = [('a', 'b'), ('a', 'c'),('d','f')]

new_data = []


for d in data                                             # loop over your data
    if new_data and new_data[-1][0] == d[0]:              # if something in new_data and 1st
        new_data[-1].extend(d[1:])                        # ones are identical: extend
    else:
        new_data.append( [a for a in d] )                 # not same/nothing in: add items

print(new_data)                   # all are lists

new_data = [tuple(x) for x in new_data]
print(new_data)                   # all are tuples again      

Вывод:

[['a', 'b', 'c'], ['d', 'f']]     # all are lists
[('a', 'b', 'c'), ('d', 'f')]     # all are tuples again   

См. Неизменные и изменяемые типы

...