4

Given an list of integers does exists a default method find the max distance between values?

So if I have this array

[1, 3, 5, 9, 15, 30]

The max step between the values is 15. Does the list object has a method for do that?

Usi Usi
  • 2,967
  • 5
  • 38
  • 69

6 Answers6

8

No, list objects have no standard "adjacent differences" method or the like. However, using the pairwise function mentioned in the itertools recipes:

def pairwise(iterable):
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

...you can (concisely and efficiently) define

>>> max(b-a for (a,b) in pairwise([1, 3, 5, 9, 15, 30]))
15
Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
  • so easy :) I think that is one of the best answer :) – Usi Usi Jun 25 '15 at 08:18
  • 1
    How to import itertools's `pairwise` function ? Or do we have to include the implementation provided in the docs Recipes. – Tanveer Alam Jun 25 '15 at 08:39
  • I also fail to import it. I use "import itertools" and then "itertools.pairwise" but it always throws an "AttributeError" while e.g. "itertools.combinations" works fine. – Cleb Jun 25 '15 at 08:56
  • @TanveerAlam, @Cleb Indeed, `pairwise` is not a function provided by the `itertools` module: it's an example mentioned in the "recipes" section I linked. I now included the definition in this answer to make it (the answer) more self-contained. – Frerich Raabe Jun 25 '15 at 09:25
  • @FrerichRaabe: Thanks for the edit, I was confused when I failed to import it. It is not a default function UsiUsi asked for but seems kind of efficient :) – Cleb Jun 25 '15 at 09:27
  • Unfortunately I get this error NameError: global name 'tee' is not defined – Usi Usi Jun 25 '15 at 14:22
  • @UsiUsi `tee` is a function from `itertools`. If you just did `import itertools` you would need to use `itertools.tee` (and `itertools.izip`). – Frerich Raabe Jun 25 '15 at 15:08
2

No, but it's trivial to code:

last = data[0]
dist = 0
for i in data[1:]:
    dist = max(dist, i-last)
    last = i
return dist
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
2

You can do:

>>> s = [1, 3, 5, 9, 15, 30]
>>> max(x[0] - x[1] for x in zip(s[1:], s))
15

This uses max and zip. It computes the difference between all consecutive elements and returns the max of those.

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
2
l=[1, 3, 5, 9, 15, 30]
max([j-i for i, j in zip(l[:-1], l[1:])]) 

That is using pure python and gives you the desired output "15".

If you like to work with "numpy" you could do:

import numpy as np
max(np.diff(l))
Cleb
  • 25,102
  • 20
  • 116
  • 151
  • Welcome :) Yes, it is my preferred one but since you asked for a default function, I was not sure whether it suits you. – Cleb Jun 25 '15 at 08:20
  • According to [this answer](http://stackoverflow.com/a/24894043/91757), the `numpy` version is actually pretty slow because it first has to convert the given list into an `ndarray`. – Frerich Raabe Jun 25 '15 at 08:26
  • @FrerichRaabe: Interesting, thanks for pointing that out! I usually don't need it in situations in which speed matters but it is good to know. – Cleb Jun 25 '15 at 08:31
0

The list object does not. However, it is pretty quick to write a function that does that:

def max_step(my_list):
    max_step = 0
    for ind in xrange(len(my_list)-1):
        step = my_list[ind+1] - my_list[ind]
        if step > max_step:
            max_step = step
    return max_step

>>> max_step([1, 3, 5, 9, 15, 30])
15

Or if you prefer even shorter:

max_step = lambda l: max([l[i+1] - l[i] for i in xrange(len(l)-1)])
>>> max_step([1, 3, 5, 9, 15, 30])
15
DevShark
  • 8,558
  • 9
  • 32
  • 56
0

It is possible to use the reduce() function, but it is not that elegant as you need some way to keep track of the previous value:

def step(maxStep, cur):
    if isinstance(maxStep, int):
        maxStep = (abs(maxStep-cur), cur)

    return (max(maxStep[0], abs(maxStep[1]-cur)), cur)

l = [1, 3, 5, 9, 15, 30]

print reduce(step, l)[0]

The solution works by returing the previous value and the accumulated max calculation as a tuple for each iteration.

Also what is the expected outcome for [10,20,30,5]? Is it 10 or 25? If 25 then you need to add abs() to your calculation.

Martin Evans
  • 45,791
  • 17
  • 81
  • 97