2011-03-15 41 views
18

Duplicar posibles:
Python - Differences between elements of a listDiferencia entre elementos consecutivos en la lista

Tengo una lista y quiero encontrar diferencias entre elementos consecutivos:

a = [0, 4, 10, 100] 
find_diff(a) 
>>> [4,6,90] 

¿Cómo lo haría codifica la función find_diff()? Puedo codificar esto con el iterador "for" pero estoy seguro de que hay formas muy simples de hacerlo con un simple trazador de líneas.

+0

hmm, que iba a aceptar la primera respuesta, pero veo que ahora se elimina. – gok

+0

También debería haber sido, ya que esa pregunta pregunta ** exactamente lo mismo **. –

+0

entonces, ¿debería eliminar esta pregunta? No pude encontrar ese en búsqueda antes de preguntar – gok

Respuesta

28

Se podría utilizar enumerate, zip y list comprehensions:

>>> a = [0, 4, 10, 100] 

# basic enumerate without condition: 
>>> [x - a[i - 1] for i, x in enumerate(a)][1:] 
[4, 6, 90] 

# enumerate with conditional inside the list comprehension: 
>>> [x - a[i - 1] for i, x in enumerate(a) if i > 0] 
[4, 6, 90] 

# the zip version seems more concise and elegant: 
>>> [t - s for s, t in zip(a, a[1:])] 
[4, 6, 90] 

En cuanto al rendimiento, parece que hay no demasiado varianza:

In [5]: %timeit [x - a[i - 1] for i, x in enumerate(a)][1:] 
1000000 loops, best of 3: 1.34 µs per loop 

In [6]: %timeit [x - a[i - 1] for i, x in enumerate(a) if i > 0] 
1000000 loops, best of 3: 1.11 µs per loop 

In [7]: %timeit [t - s for s, t in zip(a, a[1:])] 
1000000 loops, best of 3: 1.1 µs per loop 
16

Uso del recipe for pairwise de la documentación itertools:

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

Uso de esta manera:

>>> a = [0, 4, 10, 100] 
>>> [y-x for x,y in pairwise(a)] 
[4, 6, 90] 
+1

Eso es completamente innecesario. Ver [Python - Diferencias entre los elementos de una lista] (http://stackoverflow.com/questions/2400840/python-differences-between-elements-of-a-list). –

+12

@Matt Ball: muchos iteradores se pueden llamar "innecesarios", pero una vez definidos, son muy útiles para expresiones comunes. ¿Por qué pedirle al lector que descifre un zip de dos segmentos cuando podemos asignar un nombre útil a la idea como 'pairwise'. No creo que esté solo al pensar esto, ya que levanté el ejemplo directamente de los documentos. –

+0

+! Esta versión funciona para generadores arbitrarios, que no pueden ser cortados/indexados. – avmohan

3
[x - a[i-1] if i else None for i, x in enumerate(a)][1:] 
Cuestiones relacionadas