简体   繁体   中英

Summing Elements in Nested Lists with Condition Check

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM