0

An example:

l = [1, 3, 8, 10, 20]

Result:

[2, 5, 2, 10]

I want to get the difference between the two numbers

Some efforts I tried:

  1. list-comprehension, I like this but if I want to do some nested list-comprehension, it is maybe a little hard to read:
print([l[i]-l[i-1] for i in range(1, len(l))])
  1. I tried to find it in itertools.I find some very similar function like accumulate(Even functools.reduce).Exactly, they couldn't get expected result.

Does there has some function in the standard library could achieve that?like:

func(lambda x,y: x-y, l)

If this question is duplicate, please tell me and I will delete this post.Thanks <3.

Kevin Mayo
  • 1,089
  • 6
  • 19
  • ***If this question is duplicate, please tell me***: Read up on [How do I search?](https://stackoverflow.com/help/searching) and find it out yourself. – stovfl Jul 24 '20 at 15:26
  • @stovfl Sure, I must search it on the Internet before I ask this question..But I didn't find it.... – Kevin Mayo Jul 24 '20 at 15:30
  • 2
    [`numpy.diff`](https://numpy.org/doc/stable/reference/generated/numpy.diff.html). Searching _"python difference between consecutive numbers"_ gave this as the first result https://stackoverflow.com/questions/24614361/finding-the-difference-between-consecutive-numbers-in-a-list-python – Pranav Hosangadi Jul 24 '20 at 15:39
  • @PranavHosangadi Though it is not the standard module.It seems `numpy.dff` should be the only way to achieve that. – Kevin Mayo Jul 24 '20 at 15:45

2 Answers2

4

You may use zip:

l = [1, 3, 8, 10, 20]

result = [y - x for x, y in zip(l, l[1:])]
print(result)

Which yields

[2, 5, 2, 10]

zip binds together elements from multiple iterators in one tuple, l[1:] is just the slice notation for [3, 8, 10, 20] (starting at the second element, that is). You can see it yourself with:

for pair in zip(l, l[1:]):
    print(pair)

Which yields

(1, 3)
(3, 8)
(8, 10)
(10, 20)

An alternative could be:
from itertools import tee


def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)


result = list(map(lambda tpl: tpl[1] - tpl[0], pairwise(l)))
print(result)
Jan
  • 42,290
  • 8
  • 54
  • 79
  • Thanks for answer, +1 but does there have some function to do it directly?like `func(lambda x,y: x-y, l)`.This also do a list-comprehension. – Kevin Mayo Jul 24 '20 at 15:31
  • 2
    @KevinMayo: You could wrap the functionality in a function yourself. A list comprehension is usually very efficient. – Jan Jul 24 '20 at 15:38
2

Several ways:

[y - x for x, y in zip(x[:-1], x[1:])]  # [2, 5, 2, 10]

list(map(lambda xy: xy[1] - xy[0], zip(x[:-1], x[1:])))  # [2, 5, 2, 10]

Or a slightly more readable way if you write a couple boilerplace functions:

def lag(x):
    return zip(x[:-1], x[1:])

def diff(pair):
    return pair[1] - pair[0]

list(map(diff, lag(x)))

Of course, in either case you should handle corner cases around list size, etc.

TayTay
  • 6,882
  • 4
  • 44
  • 65
  • Thanks for answer, +1 but does there have some function to do it directly?like `the_standard_func(lambda x,y: x-y, l)`.This also do a list-comprehension. – Kevin Mayo Jul 24 '20 at 15:36
  • 2
    This uses stdlib for everything, and all of the code here is extremely light weight. If you are looking for a function this specific, you're probably going to need to use Numpy or something outside of stdlib. – TayTay Jul 24 '20 at 15:43