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]