I want to "sum" two lists of lists by first index.
To give an example, I have L1 and L2:
L1=[[2,"word1"],[1,"word2"],[3,"word3"]]
L2=[[7,"word4"],[6,"word1"],[3,"word5"],[6,"word3"]]
and I want this as output:
L3=[[8,"word1"],[1,"word2"],[9,"word3"],[7,"word4"],[3,"word5"]]
Of course I know how to code this but not in a very elegant way, with some while loop, and I'm wondering if there is no simpler solution...
My code so far:
def sum_list(L1,L2):
word1=[x[1] for x in L1]
word2=[x[1] for x in L2]
score1=[x[0] for x in L1]
score2=[x[0] for x in L2]
word3=[]
L3=[]
i=0
while i<len(word1):
word3.append(word1[i])
if word1[i] not in word2:
L3.append([score1[i],word1[i]])
else:
L3.append([score1[i] score2[word2.index(word1[i])],word1[i]])
i=i 1
i=0
while i<len(word2):
if word2[i] not in word3:
L3.append([score2[i],word2[i]])
i=i 1
return L3
Thanks
CodePudding user response:
You could use a Counter
for that.:
from collections import Counter
L1 = [[2, "word1"], [1, "word2"], [3, "word3"]]
L2 = [[7, "word4"], [6, "word1"], [3, "word5"], [6, "word3"]]
L1_reversed = [l[::-1] for l in L1]
L2_reversed = [l[::-1] for l in L2]
L1_counter = Counter(dict(L1_reversed))
L2_counter = Counter(dict(L2_reversed))
L3_counter = L1_counter L2_counter
print(L3_counter)
Gives:
Counter({'word3': 9, 'word1': 8, 'word4': 7, 'word5': 3, 'word2': 1})
And if you want to have your list of lists back:
L3 = [[value, key] for key, value in L3_counter.items()]
print(L3)
Which gives:
[[8, 'word1'], [1, 'word2'], [9, 'word3'], [7, 'word4'], [3, 'word5']]
The code is a bit convoluted, to change the data in the needed structure. But maybe you'd want to rethink about how you keep the data anyways as a list of list is not necessarily the best structure to represent such data. A dict would be the better representation here (no duplicates, and directly indexable by key).
CodePudding user response:
# Accumulate counts in a dict.
d = dict()
list(map(lambda p: d.__setitem__(p[1],d.setdefault(p[1], 0) p[0]), L1))
list(map(lambda p: d.__setitem__(p[1],d.setdefault(p[1], 0) p[0]), L2))
# Unpack the dict.
L3 = [[k, v] for k,v in d.items()]
print(L3)
A more verbose approach:
def accumulateInDict(d, l):
for pair in l:
key = pair[1]
count = d.get(key, 0)
d[key] = count pair[0]
# Accumulate counts in a dict.
d = dict()
accumulateInDict(d, L1)
accumulateInDict(d, L2)
# Unpack the dict.
L3 = [[k, v] for k,v in d.items()]
print(L3)