Слияние списка с общим значением элемента без его сортировки - PullRequest
0 голосов
/ 10 ноября 2018

Моя проблема в том, что у меня есть nested list

l = [
     ['a','apple',1],
     ['b', 'banana', 0], 
     ['a', 'artichoke', 'antenna'], 
     ['b', 'brocolli', 'baton'],
     ['c', None, 22]
    ]

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

[
 ['a','apple', 1, 'artichoke', 'antenna'],
 ['b', 'banana', 0, 'brocolli', 'baton'],
 ['c', None, 22]
]

Я нашел решение из здесь и здесь Но вывод, который я получаю, каким-то образом отсортирован, что касается моего текущего вывода:

[['c', None, 22], [1, 'antenna', 'apple', 'artichoke', 'a'], [0, 'b', 'banana', 'brocolli', 'baton']]

Мой код:

len_l = len(l)
i = 0
while i < (len_l - 1):
    for j in range(i + 1, len_l):

        # i,j iterate over all pairs of l's elements including new 
        # elements from merged pairs. We use len_l because len(l)
        # may change as we iterate
        i_set = set(l[i])
        j_set = set(l[j])
        if len(i_set.intersection(j_set)) > 0:
            # Remove these two from list
            l.pop(j)
            l.pop(i)

            # Merge them and append to the orig. list
            ij_union = list(i_set.union(j_set))
            l.append(ij_union)


            # len(l) has changed
            len_l -= 1

            # adjust 'i' because elements shifted
            i -= 1

            # abort inner loop, continue with next l[i]
            break
    i += 1
print(l)

Я был бы признателен за помощь здесь, и я также открыт для новых предложений о том, как сделать это более простым способом, потому что, честно говоря, я не использовал методы union() или intersection() раньше. спасибо

1 Ответ

0 голосов
/ 10 ноября 2018

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

data = [
    ['a','apple',1],
    ['b', 'banana', 0], 
    ['a', 'artichoke', 'antenna'], 
    ['b', 'brocolli', 'baton'],
    ['c', None, 22]
]

Тогда мы:

d = {} 
for k, *vals in data:
    d.setdefault(k, []).extend(vals)

При желании вы можете использовать d = collections.OrderedDict() здесь, если это абсолютно необходимо, чтобы гарантировать порядок ключей, как показано в списке.

Что дает вам d из:

{'a': ['apple', 1, 'artichoke', 'antenna'],
 'b': ['banana', 0, 'brocolli', 'baton'],
 'c': [None, 22]}

Если вы хотите распаковать обратно в списки списков (хотя, вероятно, более полезно быть dict), тогда вы можете сделать:

new_data = [[k, *v] for k, v in d.items()]

Чтобы получить:

[['a', 'apple', 1, 'artichoke', 'antenna'],
 ['b', 'banana', 0, 'brocolli', 'baton'],
 ['c', None, 22]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...