Compute the differences between the elements of two lists in python

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

Answers (7)

pygeek
pygeek

Reputation: 7414

Problem

Most Pythonic way to efficiently calculate the cartesian product of iterables and subtract the results.

Solution

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) )

References

itertools.product: https://docs.python.org/3/library/itertools.html#itertools.product

generator expressions: https://www.python.org/dev/peps/pep-0289/

Upvotes: 1

Haxername
Haxername

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

abc
abc

Reputation: 11949

You could use:

>>> np.abs(a[:, np.newaxis] - b).flatten()
array([1, 7, 6, 2, 7, 1])

Upvotes: 1

bqm1111
bqm1111

Reputation: 63

You can use python generator like this

output = [abs(i - j) for i in list1 for j in list2]

Upvotes: 1

Quang Hoang
Quang Hoang

Reputation: 150825

Let's try outer:

np.abs(np.subtract.outer(l3,l4)).ravel()

Output:

array([1, 7, 6, 2, 7, 1])

Upvotes: 3

FBruzzesi
FBruzzesi

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

Advay168
Advay168

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

Related Questions