简体   繁体   中英

How do you sum together and merge multiple numbers in a list? (Python)

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)

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]]

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

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]]
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]]

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