1

So, say I have the following list and variable i:

data = [ [1, 2, 3, 1, 1], [1, 2, 3, 0, 0], [1, 2, 3, 2, 1] ]
i = 3

I would like to create a new list which will sum together and merge numbers from each sublist the ith element upwards to produce the following:

new_data = [ [1, 2, 5], [1, 2, 3], [1, 2, 6] ]

Where I have summed from each sublist the 3rd element upwards and merged the elements together. I would like to ask how, by using the standard library in Python, I can go about achieving this for an arbitrary (integer) value of i. I have the following idea in mind but I'm not sure how to put it into real Python code:

(pseudo-code)

new_data = []
for sublist in data:
      new_data.append(elements before the ith element)
      new_data.append(ith element onwards summed together)
Coconut
  • 29
  • 10
  • Related question - https://stackoverflow.com/questions/30247666/how-do-i-merge-elements-in-a-list-together. But my question concerns numbers and merging elements for arbitrary elements. – Coconut Nov 30 '20 at 12:54
  • Could you please explain with different words the meaning of "sum together and merge numbers from each sublist the ith element upwards"? Even with the example I don't understand what you mean. Could you please also include a different example? It probably doesn't help that all three lists are identical in this example. – Stef Nov 30 '20 at 13:40
  • Thank you for letting me know, I have updated my example so each sublist is different. It should be more clear now. What I mean is that I would like to sum multiple elements together and express that sum as a single element. If you need any further clarifications, please let me know. – Coconut Nov 30 '20 at 13:59

4 Answers4

3

You can slice your inner list by index and sum the rest with the one-liner:

>>> new_data = [row[:i-1] + [sum(row[i-1:])] for row in data]
>>> new_data
[[1, 2, 5], [1, 2, 5], [1, 2, 5]]
taras
  • 6,566
  • 10
  • 39
  • 50
2

You can find a nice, "pythonic" one-liner in taras' answer:

new_data = [row[:i-1] + [sum(row[i-1:])] for row in data].

From pseudo-code to correct python code

I'll focus my answer on helping you transform your pseudo-code into python code.

Pseudo-code:

new_data = []
for sublist in data:
      new_data.append(elements before the ith element)
      new_data.append(ith element onwards summed together)

The first issue with your pseudo-code is that you are making a distinction between the list data and its sublists sublist, but you are not making a distinction between the list new_data and its sublists. Let me add a variable new_sublist in the loop:

new_data = []
for sublist in data:
      new_sublist = []
      new_sublist.append(elements before the ith element)
      new_sublist.append(ith element onwards summed together)
      new_data.append(new_sublist)

The second issue with your pseudo code: you make two calls to .append in each iteration of the loop. However, these two calls are not similar: the first call is supposed to append several elements, whereas the second call is supposed to append one element. Python makes a distinction between the two operations; if you want to add more than one element at once, use .extend instead of .append. The code becomes:

new_data = []
for sublist in data:
      new_sublist = []
      new_sublist.extend([elements before the ith element])
      new_sublist.append(ith element onwards summed together)
      new_data.append(new_sublist)

Finally we can turn your pseudo-code into proper python code, using a list slice to get the elements before the ith element, and builtin function sum along with a list slice to sum the ith element onwards:

new_data = []
for sublist in data:
      new_sublist = []
      new_sublist.extend(sublist[:i])
      new_sublist.append(sum(sublist[i:]))
      new_data.append(new_sublist)

Note that in python, looping over a list to construct a new list is such a common operation that we use the compact and elegant list comprehension syntax to do it instead of a multiline for-loop:

new_data = [sublist[:i] + [sum(sublist[i:])] for sublist in data]

Relevant documentation

Stef
  • 13,242
  • 2
  • 17
  • 28
1

You can do it like so:

def merger(data, pos):
    pos -= 1 # 0 based, your i above is 1 based

    # collection list for result
    result = []
    # go over each given inner part
    for inner in data:
        # add it up to the correct position
        result.append(inner[:pos])
        # extend it by the sum of the remainder values
        result[-1].append(sum(inner[pos:]))

    return result

data = [ [1, 2, 3, 1, 1], [1, 2, 3, 1, 1], [1, 2, 3, 1, 1] ]
i = 3

print(merger(data,i)) 

Output:

[[1, 2, 5], [1, 2, 5], [1, 2, 5]]

or in short:

def merger(data, pos):
    return [[inner[: pos - 1] + [sum(inner[pos - 1 :])] for inner in data]]
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
1
data = [ [1, 2, 3, 1, 1], [1, 2, 3, 1, 1], [1, 2, 3, 1, 1] ]
i = 3
new_data = [sublist[:i-1] + [sum(sublist[i-1:])] for sublist in data]
print(new_data)
>>> [[1, 2, 5], [1, 2, 5], [1, 2, 5]]
abe
  • 957
  • 5
  • 10