Using zip_longest to sum different length lists and fill different lengths from start rather than end

谁说我不能喝 提交于 2021-02-11 14:39:46

问题


I have two lists [1,2,3,4] and [1,2,3]

I would like to sum these to give me the following: [1,3,5,7].

This was done by doing 1+0=1, 2+1=3, 3+2=5 and 4+3=7.

I understand that itertools.zip_longest would do this, but it would fill the mismatch in length with 0 at the end, giving me [2,3,6,4] and not the value I want.

I would like the mismatch in length to be solved by filling the first length with zero.


回答1:


The built-in reversed() function could be used to do it like this:

from itertools import zip_longest    

def sum_lists(*iterables):
    iterables = (reversed(it) for it in iterables)
    return list(reversed([a+b for a, b in zip_longest(*iterables, fillvalue=0)]))


if __name__ == '__main__':
    result = sum_lists([1, 2, 3, 4], [1, 2, 3])
    print(result)  # -> [1, 3, 5, 7]
    result = sum_lists([1, 2, 3], [1, 2, 3, 4])
    print(result)  # -> [1, 3, 5, 7]    # Order of args doesn't matter.



回答2:


You can pad the second list with zeros and use zip:

s1, s2 = [1,2,3,4], [1, 2, 3]
new_result = [a+b for a, b in zip(s1, ([0]*(len(s1)-len(s2)))+s2)]

Output:

[1, 3, 5, 7]



回答3:


You could build a shift by using repeat, then concatenate the shift with the shorter one using chain:

from itertools import repeat, chain

first = [1, 2, 3, 4]
second = [1, 2, 3]

shift = repeat(0, abs(len(first) - len(second)))

result = [a + b for a, b in zip(first, chain(shift, second))]

print(result)

Output

[1, 3, 5, 7]



回答4:


You can use the reversed function to generate the two lists in reverse order so that zip_longest would align the zipping from the other end, and then reverse the result afterwards:

from itertools import zip_longest
lists = [1,2,3,4], [1, 2, 3]
print(list(map(sum, zip_longest(*map(reversed, lists), fillvalue=0)))[::-1])

This outputs:

[1, 3, 5, 7]



回答5:


You could go around this problem be reversing your lists befor ziping with zip_longest.

from itertools import zip_longest

s1, s2 = [1,2,3,4], [1, 2, 3]
res = [a+b for a, b in zip_longest(reversed(s1), reversed(s2), fillvalue=0)]

and finally, reverse again, to produce the desired result:

res = res[::-1]
print(res)  # [1, 3, 5, 7]

The main advantage of this method as @CoryKramer says in his comment is that you do not have to know beforehand which list is the longest.



来源:https://stackoverflow.com/questions/54184575/using-zip-longest-to-sum-different-length-lists-and-fill-different-lengths-from

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!