2

How can I compare one element with the next one in a sorted list, and print out their differences. Any help would be appreciated.

Eg: 
lst = [3.18,10.57,14.95,...]
10.57 - 3.18 =  7.39
14.95 - 10.57 = 4.38
...
DGT
  • 2,604
  • 13
  • 41
  • 60
  • Please post the code you have written so far; and please use the homework tag. – Pete Wilson May 29 '11 at 00:51
  • maybe not related but I found this post to be most helpful: http://stackoverflow.com/questions/942543/operation-on-every-pair-of-element-in-a-list – Hassek May 22 '14 at 17:56

5 Answers5

6
it = iter(lst)
it.next()
print [(x, y, y - x) for (x, y) in itertools.izip(lst, it)]
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
6

If you are manipulating numerical data, consider using numpy

import numpy as np

lst = [3.18,10.57,14.95]
arr = np.array(lst)

diff = np.diff(arr)

>>> diff
array([ 7.39,  4.38])

You can convert it back to list if you have to:

diff_list = list(diff)

Otherwise you can iterate over it just like you iterate over a list:

for item in diff: 
    print(item)

7.39
4.38

EDIT: the five solutions I timed were pretty close to each other, so choose the one that's easier to read

t = timeit.Timer("[b - a for a, b in zip(l, l[1:])]", "l = range(int(1e6))")
print(t.timeit(1))
>>> 0.523894071579

t = timeit.Timer("list(np.diff(np.array(l)))", "import numpy as np; l = range(int(1e6))")
print(t.timeit(1))
>>> 0.484916915894

t = timeit.Timer("diffs = [l[x + 1] - l[x] for x in range(len(l) - 1)]", "l = range(int(1e6))")
print(t.timeit(1))
>>> 0.363043069839

t = timeit.Timer("[(x, y, y - x) for (x, y) in itertools.izip(l, it)]", "l = range(int(1e6)); it = iter(l); it.next()")
print(t.timeit(1))
>>> 0.54354596138

# pairwise solution
t = timeit.Timer("a, b = itertools.tee(l); next(b, None); [(x, y) for x, y in itertools.izip(a, b)]", "l = range(int(1e6));")
print(t.timeit(1))
>>> 0.477301120758
AnalyticsBuilder
  • 4,111
  • 4
  • 24
  • 36
  • 1
    If you are using numpy already, you might as well use numpy.diff, which does exactly what DGT is looking for - no need to create additional copies of the original list. – Jim Brissom May 29 '11 at 01:24
4

You need the pairwise() recipe from itertools, from where lots of Python goodness comes.

>>> for x,y in pairwise(lst): 
...     print(y, " - ", x, " = ", y - x)
... 
10.57  -  3.18  =  7.390000000000001
14.95  -  10.57  =  4.379999999999999
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
  • 1
    +1, `pairwise` is sweet, it would be neat if it together with `grouper` would make it into iterools proper... – Skurmedel May 29 '11 at 01:04
3
diffs = [lst[x + 1] - lst[x] for x in range(len(lst) - 1)]
for x in diffs:
    print x 
Rafe Kettler
  • 75,757
  • 21
  • 156
  • 151
3

Use zip, and zip the list with itself.

l = [1, 2, 4, 7]
[b - a for a, b in zip(l, l[1:])]

# [1, 2, 3]
Eevee
  • 47,412
  • 11
  • 95
  • 127
  • Note that this will create a copy of `l` (less its first element) and then (in Python < 3) create *another* list containing all the elements of `l` plus all the elements of its copy. You should prefer an `iter`-based solution (such as [mine](http://stackoverflow.com/questions/6165277/compare-list-elements/6165319#6165319) or [Ignacio's](http://stackoverflow.com/questions/6165277/compare-list-elements/6165291#6165291) ), particularly if your `list` is large! – johnsyweb May 29 '11 at 01:29