[英]Python lists -- deduping and adding sub-list element
Input:输入:
a = [[['a','b'],3],[['b','a'],9],[['b','z'],4]]
Desired Output (dedupe regardless of order and add integers)所需的输出(重复数据删除不考虑顺序并添加整数)
[[['a','b'],12],[['b','z'],4]]
This does not work of course:这当然不起作用:
a2 = [sorted(list) for list in [i[0] for i in a]]
print(a2)
[['a', 'b'], ['a', 'b'], ['b', 'z']]
which can be deduped of course:当然可以删除:
a3= []
for i in a2:
if i not in a3:
a3.append(i)
print(a3)
[['a', 'b'], ['b', 'z']]
But of course I am losing the counts for the sub-list being deduped.但当然,我正在丢失被重复数据删除的子列表的计数。 Any advice?有什么建议吗?
Thanks.谢谢。
I guess this is what you want:我想这就是你想要的:
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]]
you can use:您可以使用:
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
output:输出:
[[['a', 'b'], 12], [['b', 'z'], 4]]
or you can use:或者你可以使用:
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
output:输出:
[[['a', 'b'], 12], [['b', 'z'], 4]]
if you like one-line solution:如果您喜欢单线解决方案:
[[list(k), v] for k, v in reduce(add, map(Counter, ({frozenset(k): v} for k, v in a))).items()]
output:输出:
[[['a', 'b'], 12], [['b', 'z'], 4]]
You can convert the sub-lists to frozensets first so that you can treat them as keys and use collections.Counter
to add the integers as counts for each distinct key, and then convert the frozensets back to lists when iterating through the resulting items:您可以先将子列表转换为frozensets,以便您可以将它们视为键并使用collections.Counter
将整数添加为每个不同键的计数,然后在迭代结果项时将frozensets转换回列表:
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()])
This will do the trick:这将解决问题:
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]))]
Outputs:输出:
[[['a', 'b'], 12], [['b', 'z'], 4]]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.