Summary: The most pythonic approach to add two lists element-wise is to use zip()
to pair the elements at the same positions in both lists and then add the two elements. Here’s a quick look at the solution: [x + y for x, y in zip(li_1, li_2)]
. An alternate proposition to this without using zip: [li_1[i]+li_2[i] for i in range(len(li_smaller))]
Problem Formulation
Problem Statement: Given two lists, how will you add the two lists element-wise?
Example: Consider that you have the following lists:
Input:
li_1 = [2,4,6]
li_2 = [1,3,5]
Expected Output:
[3,7,11]
Challenge: How will you perform an element-wise addition of the two lists as shown below:
๐นVideo Walkthrough
Solution 1: The Naive Approach
Approach:
- The basic solution to this problem is to find out the length of the smaller list.
- Then use a for loop to iterate across all the items of each list. Note that the range of iteration will be determined by the length of the smaller list.
- In every iteration, select an element from each list with the help of its index and then add them up.
- You can store the output generated in each iteration within another list and finally display the resultant list as an output.
Code:
# Given Lists li_1 = [2, 4, 6] li_2 = [1, 3, 5, 15] res = [] # resultant list to store the output # Find the smaller list li_smaller = li_1 if len(li_2) > len(li_1) else li_2 for i in range(len(li_smaller)): # add each item from each list one by one res.append(li_1[i] + li_2[i]) print(res)
Output:
[3, 7, 11]
The above solution can further be compressed with the help of a list comprehension, as shown below:
# Given Lists li_1 = [2, 4, 6] li_2 = [1, 3, 5, 15] # Find the smaller list li_smaller = li_1 if len(li_2) > len(li_1) else li_2 res = [li_1[i]+li_2[i] for i in range(len(li_smaller))] print(res)
Let’s try to understand the working principle behind the list comprehension used in the above snippet.
The first part is the expression. In the above snippet, li_1[i]+li_2[i]
is the expression that denotes the element-wise addition of the two lists. The second part represents the context which represents the counter variable i
that ranges from 0 until the length of the smaller list. It is basically keeping track of the index of each element in the lists.
Solution 2: Using zip and List Comprehension
Approach: A more pythonic solution to the given problem is to pass both the lists into the zip()
method. This returns a tuple consisting of elements in pairs that are at the same position in each list. Once you get the pair of elements, you can simply add them up. All of this can be performed within a list comprehension.
Code:
li_1 = [2, 4, 6] li_2 = [1, 3, 5, 15] res = [x + y for x, y in zip(li_1, li_2)] print(res) # OUTPUT: [3, 7, 11]
An advantage of using this approach over the previous solution is not only is it a more pythonic way of adding the two lists, but it also eliminates the necessity to explicitly find out the length of the smaller list in case the two lists have different lengths.
A Quick Recap to Zip():
The zip()
function takes an arbitrary number of iterables and aggregates them to a single iterable, a zip object. It combines the i-th values of each iterable argument into a tuple. Hence, if you pass two iterables, each tuple will contain two values. If you pass three iterables, each tuple will contain three values. For example, zip together lists [1, 2, 3]
and [4, 5, 6]
to [(1,4), (2,5), (3,6)]
.
Read More: Python Zip โ A Helpful Illustrated Guide
๐Finding Sum of Two Lists Element-wise for list of lists
li = [[1, 2, 3], [4, 5, 6]] res = [a + b for a, b in zip(*li)] print(res) # [5, 7, 9]
Solution 3: Using map() and add()
Prerequisites:
๐ Python facilitates us with many predefined functions for numerous mathematical, logical, relational, bitwise etc operations. These functions are contained within the operator module. One such function is add(a,b)
, which returns the result of the addition of the two arguments, i.e., a+b
.
๐ The map()
function transforms one or more iterables into a new one by applying a โtransformator functionโ to the i-th elements of each iterable. The arguments are the transformator function object and one or more iterables. If you pass n iterables as arguments, the transformator function must be an n-ary function taking n input arguments. The return value is an iterable map object of transformed, and possibly aggregated, elements.
Approach: Pass the input lists and the add()
function within the built-in method map()
. The add()
method will simply add the elements of the two lists and then return an iterable. This iterable can then be converted to a list using the list constructor.
Code:
from operator import add li_1 = [2, 4, 6] li_2 = [1, 3, 5, 15] res = list(map(add, li_1, li_2)) print(res)
Output:
[3, 7, 11]
๐Finding Sum of Two Lists Element-wise for Unknown Number of Lists of Same Length
def sum_li(*args): return list(map(sum, zip(*args))) res = sum_li([1, 2, 3], [4, 5, 6], [7, 8, 9]) print(res) # [12, 15, 18]
Method 4: Using zip_longest from Itertools Module
Until now, all the solutions considered the length of the smaller list. What if you want to add the elements considering the length of the larger list. In other words, consider the following scenario:
Given:
li_1 = [2, 4, 6]
li_2 = [1, 3, 5, 15]
Expected Output:
[3, 7, 11, 15]
Approach: To deal with this scenario, you can use the zip_longest
method of the itertools module. Not only will this method group the elements at the same position in each list, but it also allows you to take the remaining elements of the longer list into consideration.
- Pass the two lists within the
zip_longest()
function and assign0
thefillvalue
parameter. - If all the items from the smaller list get exhausted, then the remaining values will be filled by the value that has been assigned to the
fillvalue
parameter. - Finally, perform the addition of elements at the same position that have been paired by the
zip_longest
method using thesum()
function.
Code:
from itertools import zip_longest li_1 = [2, 4, 6] li_2 = [1, 3, 5, 15] res = [sum(x) for x in zip_longest(li_1, li_2, fillvalue=0)] print(res)
Output:
[3, 7, 11, 15]
Method 5: Using Numpy
If you have two lists that have the same length, then using Numpy can be your best bet. There are two ways of implementing the solution that you need. Let’s have a look at them one by one:
The + Operator
You can simply create two numpy arrays from the two lists and then find their sum using the + operator. Easy peasy!
import numpy as np li_1 = [2, 4, 6] li_2 = [1, 3, 5] a = np.array(li_1) b = np.array(li_2) print(a+b) # [ 3 7 11]
numpy.add
The alternate formulation to the above solution is to use the numpy.add() method instead of directly using the + operator.
import numpy as np li_1 = [2, 4, 6] li_2 = [1, 3, 5] res = np.add(li_1, li_2) print(res) # [ 3 7 11]
Conclusion
Phew! We unearthed a wealth of solutions to the given problem. Please feel free to use any solution that suits you. Here’s a general recommendation to use the above approaches:
- Using
zip
is probably the most pythonic approach when you have simple lists at your disposal. - In case you do not wish to use
zip
, you can simply use a list comprehension as discussed in the first solution. - For lists with different lengths, you may use the
zip_longest
method to solve your problem.
Happy learning! ๐