Python списки - дедупликация и добавление элемента подсписка - PullRequest
2 голосов
/ 28 марта 2020

Ввод:

a = [[['a','b'],3],[['b','a'],9],[['b','z'],4]]

Требуемый вывод (дедупликация независимо от порядка и добавление целых чисел)

[[['a','b'],12],[['b','z'],4]]

Это не работает конечно:

a2 = [sorted(list) for list in [i[0] for i in a]]

print(a2)

[['a', 'b'], ['a', 'b'], ['b', 'z']]

, который, конечно, можно дедуплировать:

a3= [] 

for i in a2: 
    if i not in a3: 
       a3.append(i)

print(a3)

[['a', 'b'], ['b', 'z']]

Но, конечно, я теряю счет для дедупликации подсписка. Любой совет?
Спасибо.

Ответы [ 4 ]

3 голосов
/ 28 марта 2020

Я думаю, это то, что вы хотите:

a = [[['a','b'],3],[['b','a'],9],[['b','z'],4]]

# we use a dict to do the job.
# we sort the list of char and change to tuple. So i can be use as key.
dct = {}

for i in a:
    srt = tuple(sorted(i[0]))
    if srt in dct:
        # the tuple of char is already existing as key, just sum int.
        dct[srt]+= i[1]
    else:
        # if not we had a new key
        dct[srt] = i[1]
# Convert the dict to list of list
new_list = [[list(k),v] for k,v in dct.items()]
print(new_list) # [[['a', 'b'], 12], [['b', 'z'], 4]]
2 голосов
/ 28 марта 2020

вы можете использовать:

from collections import defaultdict

a = [[['a','b'],3],[['b','a'],9],[['b','z'],4]]
d = defaultdict(lambda : 0)

for e, n in a:
    d[frozenset(e)] += n

a =  [[list(k), v]  for k, v in d.items()]
a

выход:

[[['a', 'b'], 12], [['b', 'z'], 4]]

или вы можете использовать:

from functools import reduce
from operator import add
from collections import Counter

f = ({frozenset(k): v} for k, v in a) 
d = reduce(add, map(Counter, f)) # sum unique data
result = [[list(k), v]  for k, v in d.items()]
result

выход:

[[['a', 'b'], 12], [['b', 'z'], 4]]

если вам нравится однострочное решение:

 [[list(k), v] for k, v in reduce(add, map(Counter, ({frozenset(k): v} for k, v in a))).items()]

вывод:

[[['a', 'b'], 12], [['b', 'z'], 4]]
1 голос
/ 28 марта 2020

Вы можете сначала преобразовать подсписки в frozensets, чтобы их можно было обрабатывать как ключи, и использовать collections.Counter для добавления целых чисел в качестве счетчиков для каждого отдельного ключа, а затем преобразовывать заморозки обратно в списки при повторении полученного результата. предметы:

from collections import Counter
counter = Counter()
for t, c in a:
    counter.update({frozenset(t): c})
print([[list(t), c] for t, c in counter.items()])
0 голосов
/ 28 марта 2020

Это поможет:

from itertools import groupby

a = [[['a','b'],3],[['b','a'],9],[['b','z'],4]]

# this will ensure a is ordered by the merging key:
a=sorted(a, key=lambda x: sorted(x[0]))

# this will group by merging key, extract the value with index 1, and sum it:
a=[[k, sum(map(lambda z: z[1], v))] for k,v in groupby(a, key=lambda x: sorted(x[0]))]

Выходы:

[[['a', 'b'], 12], [['b', 'z'], 4]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...