Home > Back-end >  element-wise summation of some lists
element-wise summation of some lists

Time:10-15

I need to write a function that takes two lists and returns a new list containing the element-wise summary of lst1 and lst2. And lst1 and lst2 might have different lengths. If lst1 = [a, b, c] and lst2 = [d, e], the function should return [a d, b e, c].

Here is my code

def elem_sum(lst1: list[int], lst2: list[int]) -> list[int]:
    result = []
    number_storing = 0
    for i in range(len(lst1)):
        for j in range(len(lst2)):
            if (lst1[i] and lst2[j]) != 0:
                number_storing = lst1[i]   lst2[j]
                result.append(number_storing)
            else:
                result.append(lst2[j])

    return result
The result should be
elem_sum([1, 2, 3], [10, 20]) == [11, 22, 3]
elem_sum([1, 2, 3], [10, 20, 30, 40]) == [11, 22, 33, 40]

However, it just adds up all the numbers directly, and I have no idea how to fix it. It is better than using a while or for loop to finish it instead of using the other built-in functions as I am a beginner.

CodePudding user response:

This should work (using for loop, as you requested):

def elem_sum(lst1: list[int], lst2: list[int]) -> list[int]:
    big_lst = lst1 if len(lst1) >= len(lst2) else lst2
    small_lst = lst1 if big_lst == lst2 else lst2
    result = big_lst.copy()
    for i, value in enumerate(small_lst):
        result[i]  = value

    return result

CodePudding user response:

The absolute easiest solution is to use itertools.zip_longest, which takes two lists of unequal length and gives you pairs of values (with a "fill value" as stand-ins for missing elements from the shorter list):

from itertools import zip_longest

def elem_sum(lst1: list[int], lst2: list[int]) -> list[int]:
    return [a   b for a, b in zip_longest(lst1, lst2, fillvalue=0)]

If you want to reimplement zip_longest inside of your function rather than importing it from itertools, that might look something like this:

def elem_sum(lst1: list[int], lst2: list[int]) -> list[int]:
    result = []
    for i in range(max(len(lst1), len(lst2))):
        a = lst1[i] if i < len(lst1) else 0
        b = lst2[i] if i < len(lst2) else 0
        result.append(a   b)
    return result

CodePudding user response:

Use itertools.zip_longest to iterate on both list at the same time, and have a default value for the shortest one

def elem_sum(lst1: list[int], lst2: list[int]) -> list[int]:
    return [sum(row) for row in zip_longest(lst1, lst2, fillvalue=0)]

print(elem_sum([1, 2, 3], [10, 20]))  # [11, 22, 3]
print(elem_sum([1, 2, 3], [10, 20, 30, 40]))  # [11, 22, 33, 40]

Note that when using nested loops, as you were doing, you're doing len(lst1) * len(lst2) operations, here 3*2 => 6 , that has no sense regarding the task do to thing by pair, you only need to do max(len(lst1),len(lst2)) operations

for i in range(len(lst1)):
    for j in range(len(lst2)):

CodePudding user response:

Try using list comprehension, like so:

def elem_sum(lst1, lst2):
    short_lst, long_lst = (lst1, lst2) if len(lst1)<len(lst2) else (lst2, lst1)
    return [(0 if i>=len(short_lst) else short_lst[i])   n for i, n in enumerate(long_lst)]

It may seem a little complicated for a beginner (trust me though, I'm also a beginner), but its actually quite simple way to solve the problem using pythonic syntax.

Basically, the solution sorts the two lists into the shortest and longest based on length and then iterates through the long list, adding the value from each iteration to the value from the short list which has the same index. If the value of the index exceeds the number of elements in the short list, then 0 is added to the value from the long list instead.

Note that list comprehension is like a for-loop but in one line, and it is used to produce lists. It's a generator. You can read more about them here.

Test:

>>>print(elem_sum([1, 91, 5], [7, 2, 15, 26]))
[8, 93, 20, 26]
  • Related