-2

There are many ways to take the difference of neighboring elements and create a new difference list. Examples are given here. However, I have too many lists and I need to create difference lists of each. I do not want to write the same thing over and over. What is the shortest (and/or) efficient way to do it?

For example, say, I have list1, list2, ..., listn and I want to create d_list1, d_list2, ..., d_listn. Where d_list is the list that is created by list1[i+1]-list1[i]. Same applies for d_list2 where elements are list2[i+1]-list2[i].

1 Answers1

2

Put all your lists in a list of lists. Then zip them together with an offset. This will give you pairs of lists. Then zip those and subtract:

l1 = [1, 2, 3, 4]
l2 = [10, 20, 30, 40]
l3 = [11, 12, 13, 14]
l4 = [21, 22, 23, 24]

lists = [l1, l2, l3, l4]

[[a - b for a, b in zip(l2, l1)] for l1, l2 in zip(lists, lists[1:])]

This will give you a list of lists of differences:

[[9, 18, 27, 36], [1, -8, -17, -26], [10, 10, 10, 10]]

If you truly have a lot of lists, it may be worth using Numpy, which has a diff function:

import numpy as np

a = np.array([
    [1, 2, 3, 4],
    [10, 20, 30, 40],
    [11, 12, 13, 14],
    [21, 22, 23, 24]
])

np.diff(a, axis=0)

Giving:

array([[  9,  18,  27,  36],
       [  1,  -8, -17, -26],
       [ 10,  10,  10,  10]])

EDIT based on comment

To take the diff on the other axis, you don't need the outside zip, just the inner one:

l1 = [1, 2, 3, 4]
l2 = [10, 20, 30, 40]
l3 = [11, 12, 13, 14]
l4 = [21, 22, 23, 24]

lists = [l1, l2, l3, l4]

[[b - a for a, b in zip(l, l[1:])] for l in lists]

Giving:

[[1, 1, 1], [10, 10, 10], [1, 1, 1], [1, 1, 1]]

And in Numpy, just change the axis:

np.diff(a, axis=1)

which produces the same as a Numpy array:

array([[ 1,  1,  1],
       [10, 10, 10],
       [ 1,  1,  1],
       [ 1,  1,  1]])
Mark
  • 90,562
  • 7
  • 108
  • 148
  • Thank you! I'm sorry if it wasn't clear but I do not want to take the difference between lists. I want to take differences within a list for many lists. What you do is list2[i]-list1[i] but I want to do list1[i+1]-list1[i] for all the lists. So for your first example, the return should be [[1,1,1,1] [10,10,10,10],[1,1,1,1],[1,1,1,1]]. – Thunder Owl Jan 19 '23 at 00:50
  • @ThunderOwl see the edit. It's the same idea, but with one less zip needed. Also, you won't get 4 elements, only three. – Mark Jan 19 '23 at 00:56