Reputation: 179
I've a list of lists, and each inner list has three objects. I'd like to sum the 1st index (2nd object) of each sublist, but only if the other two objects in the sublists are the same. For example:
list_in = [['aa', 2, 'bb'], ['aa', 2, 'bb']]
Since 'aa'
and 'bb'
are the same, I'd like to add the 2 and 2 to equal 4, and output this into a new list:
list_out = ['aa', 4, 'bb']
So I need an if
statement. I tried this with the following:
list_out = []
if i[0]==i[0] for i in list_in:
total = [sum(list_in[1]) for i in range(len(list_in))]
list_out.append(i[0], total, i[2])
But python gives me an InvalidSyntax
error. I'm unsure how to fix this.
Then I tried to just construct a new list based on the condition that if the 1st and 3rd objects are the same, sum the 2nd objects:
list_out, total = [], 0
for i in list_in: # "i" is a list within the "list_in" list.
x, y, z = i[0], i[1], i[2]
if x not in list_out and z not in list_out:
list_out.append([x, y, z])
elif x in list_out and z in list_out:
total_y += y
list_out.append([x, total_y, z])
return list_out
However, this just gives me the same list as I started with. Apparently the if
and elif
statements aren't working correctly.
Upvotes: 1
Views: 305
Reputation: 71451
You can use itertools.groupby
:
import itertools
list_in = [['aa', 2, 'bb'], ['aa', 2, 'bb']]
new_list = [(a, list(b)) for a, b in itertools.groupby(sorted(list_in, key=lambda x:(x[0], x[-1])), key=lambda x:(x[0], x[-1]))]
final_data = [[a, sum(c[1] for c in d), b] for (a, b), d in new_list][0]
Output:
['aa', 4, 'bb']
itertools.groupby
allows for a more generic solution should the length of list_in
exceed two.
Edit: the solution will work for larger lists:
list_in = [['aa', 2, 'bb'], ['aa', 2, 'bb'], ['aa', 15, 'bb']]
new_list = [(a, list(b)) for a, b in itertools.groupby(sorted(list_in, key=lambda x:(x[0], x[-1])), key=lambda x:(x[0], x[-1]))]
final_data = [[a, sum(c[1] for c in d), b] for (a, b), d in new_list][0]
Output:
['aa', 19, 'bb']
In Python, a function is an object. A lambda
function is known as an "anonymous function" because when its object is created, it is not bound to a name. Instead, the function object itself is returned.
Upvotes: 4
Reputation: 51653
I think I am doing manually what Ajax1234 does with groupby, here it comes:
list_in = [['aa', 2, 'bb'], ['aa', 2, 'bb']]
grp = {}
for inner in list_in:
key = (inner[0],inner[-1]) # tuple is immutable and can be key
grp.setdefault(key,0) # create key if needed with value 0
grp[key]+=inner[1] # add value
list_out = [[k[0],grp[k],k[1]] for k in grp] # reassemble from dictionary
print(list_out)
Output:
[['aa', 4, 'bb']]
This will also include any sublist that has NO duplicate entry. Not sure if thats ok.
Upvotes: 1