Reputation: 509
I want to subtract the element of two list from each other and make a list out them with a clean and efficient code in python:
For Example, given two lists [2,7,8]
, [1,9]
, subtracting(pairwise) the elements would give: [1, 7, 6, 2, 7, 1]
.
I came up with two codes:
Code 1 :
l1,l2 = [1], [3,4]
l3,l4 = [2,7,8], [1,9]
def computedifference(list1,list2):
output = []
for i in list1:
for j in list2:
output.append(abs(i-j))
return output
print(computedifference(l1,l2))
print(computedifference(l3,l4))
Code 2:
import numpy as np
l1,l2 = [1], [3,4]
l3,l4 = [2,7,8], [1,9]
def computedifference(list1,list2):
output1 = [ np.asarray(list1)-x for x in np.asarray(list2)]
output = [np.abs(x) for x in output1]
return output
print(computedifference(l1,l2))
print(computedifference(l3,l4))
Expected output
[2, 3]
[1, 7, 6, 2, 7, 1]
Is there a better, pythonic and efficient way?
Upvotes: 0
Views: 158
Reputation: 7414
Most Pythonic way to efficiently calculate the cartesian product of iterables and subtract the results.
The simplest and most pythonic approach:
[ abs(i-j) for i,j in itertools.product(list1, list2) ]
Depending on how large your dataset is, you may need to use a generator expression instead.
( abs(i-j) for i,j in itertools.product(list1, list2) )
Note that you don't need to explicitly define l1 and l2 since itertools.product takes n
iterables. You can simply do:
l = [[1], [3,4]]
( abs(i-j) for i,j in itertools.product(*l) )
itertools.product: https://docs.python.org/3/library/itertools.html#itertools.product
generator expressions: https://www.python.org/dev/peps/pep-0289/
Upvotes: 1
Reputation: 9
l1 = [2,7,8]
l2 = [1,9]
def computedDiff(list1,list2):
return([abs(i-j) for i in list1 for j in list2])
print(computedDiff(l1,l2))
Ok so basically what I did here is compressed it to one line, and and am just returning the entire for loop in list form. Just a cleaner way since it does not include any other variables or appending to a list.
Upvotes: 1
Reputation: 11949
You could use:
>>> np.abs(a[:, np.newaxis] - b).flatten()
array([1, 7, 6, 2, 7, 1])
Upvotes: 1
Reputation: 63
You can use python generator like this
output = [abs(i - j) for i in list1 for j in list2]
Upvotes: 1
Reputation: 150825
Let's try outer
:
np.abs(np.subtract.outer(l3,l4)).ravel()
Output:
array([1, 7, 6, 2, 7, 1])
Upvotes: 3
Reputation: 6505
You can use numpy broadcasting to vectorize the pairwise difference:
import numpy as np
l1, l2 = [1], [3,4]
l3, l4 = [2,7,8], [1,9]
def computedifference(list1, list2):
l1 = np.array(list1)
l2 = np.array(list2)
return np.abs(l1[:,None] - l2).ravel().tolist()
computedifference(l1,l2)
[2, 3]
computedifference(l3,l4)
[1, 7, 6, 2, 7, 1]
Upvotes: 1
Reputation: 627
import itertools
def computedifference(list1,list2):
return [abs(i-j) for i,j in itertools.product(list1,list2)]
documentation for itertools.product : https://docs.python.org/2/library/itertools.html#itertools.product
Upvotes: 1