-3

So, I have a list that looks something like this

[[[1, 2], [3, 4], [5, 6]],
 [[7, 8], [9, 10], [11, 12]],
 [[13, 14], [15, 16], [17, 18]],
 [[19, 20], [21, 22], [23, 24]]]

And I want it to look like this

[[3, 7, 11],
 [15, 19, 23],
 [27, 31, 35],
 [39, 43, 27]]

that is 3 = sum([1, 2]), 7 = sum([3, 4]), ....

I have tried nesting for loops but I haven't found anything that got the desired result, does anyone know how I could do this?

ruohola
  • 21,987
  • 6
  • 62
  • 97
Robert
  • 21

4 Answers4

3

Although I nowadays think that the list comprehension method would be clearer for this, you can do this quite cleanly without them as well:

lists = [[[1, 2], [3, 4], [5, 6]],
        [[7, 8], [9, 10], [11, 12]],
        [[13, 14], [15, 16], [17, 18]],
        [[19, 20], [21, 22], [23, 24]]]

new_lists = []
for nested in lists:
    new_ls = []
    for ls in nested:
        new_ls.append(sum(ls))
    new_lists.append(new_ls)


>>> new_lists
[[3, 7, 11], [15, 19, 23], [27, 31, 35], [39, 43, 47]]
ruohola
  • 21,987
  • 6
  • 62
  • 97
3

You could also use list comprehensions:

[[sum(x) for x in triple] for triple in lists]

In the above list comprehension, triple will be your list of three doubles so the first for loop will be covering these. x will then be each list of doubles, inside of the triple so we are summing it, while keeping it inside the original triple by using this bracket around:

[sum(x) for x in triple]

output:

[[3, 7, 11], [15, 19, 23], [27, 31, 35], [39, 43, 47]]
d_kennetz
  • 5,219
  • 5
  • 21
  • 44
1

If you are happy to use a 3rd party library, you can use NumPy and sum along a single dimension:

import numpy as np

A = np.array([[[1, 2], [3, 4], [5, 6]],
              [[7, 8], [9, 10], [11, 12]],
              [[13, 14], [15, 16], [17, 18]],
              [[19, 20], [21, 22], [23, 24]]])

res = A.sum(2)

Result:

array([[ 3,  7, 11],
       [15, 19, 23],
       [27, 31, 35],
       [39, 43, 47]])

See also: What are the advantages of NumPy over regular Python lists?

jpp
  • 159,742
  • 34
  • 281
  • 339
0

We could look at a general case where your list may have an nondetermined depth of nested lists, and the nesting may be different at different places, so forming a tree.

You can then use a recursive solution that finds the "leaves" of the tree, i.e. lists that don't contain other lists, and sum up those.

Here is how that looks:

def sum_numbers(lst):
    if any(isinstance(item, list) for item in lst):
        return [sum_numbers(item) if isinstance(item, list) else item 
                for item in lst]
    else:
        return sum(lst)

Here is some input data that has such irregular shape:

data = [[[1, 2, [3, 4], 5, 6]],
        [[7, 8], 9, [10, [11, 12]]],
        [[13, 14, 15], [16, 17, 18]],
        [19, [20, 21], 22], 23, 24]

The tree returned by the function will have decreased in height, and if you feed the result back into the function, you can repeatedly reduce the tree until it becomes a single number:

print(data)
while isinstance(data, list):
    data = sum_numbers(data)
    print(data)

The output generated for the above example is:

[[[1, 2, [3, 4], 5, 6]], [[7, 8], 9, [10, [11, 12]]], [[13, 14, 15], [16, 17, 18]], [19, [20, 21], 22], 23, 24]
[[[1, 2, 7, 5, 6]], [15, 9, [10, 23]], [42, 51], [19, 41, 22], 23, 24]
[[21], [15, 9, 33], 93, 82, 23, 24]
[21, 57, 93, 82, 23, 24]
300
trincot
  • 317,000
  • 35
  • 244
  • 286