a = [5, 66, 7, 8, 9, ...]
¿Es posible hacer una iteración en lugar de escribir de esta manera?recorrido por pares de una lista o tupla
a[1] - a[0]
a[2] - a[1]
a[3] - a[2]
a[4] - a[3]
...
Gracias!
a = [5, 66, 7, 8, 9, ...]
¿Es posible hacer una iteración en lugar de escribir de esta manera?recorrido por pares de una lista o tupla
a[1] - a[0]
a[2] - a[1]
a[3] - a[2]
a[4] - a[3]
...
Gracias!
Claro.
for i in range(1, len(a)):
print a[i] - a[i-1]
No veo cuál es el verdadero problema aquí. ¿Has leído the python tutorial?
para una pequeña lista en Python 2 o cualquier lista en Python 3, puede utilizar
[x - y for x, y in zip(a[1:], a)]
para una lista más grande, es probable que desee
import itertools as it
[x - y for x, y in it.izip(a[1:], a)]
si está utilizando Python 2
Y consideraría escribirlo como una expresión de generador en su lugar
(x - y for x, y in it.izip(a[1:], a))
Esto evitará crear la segunda lista en la memoria de una vez, pero solo podrá iterar una vez. Si solo quiere para iterar sobre él una vez, entonces esto es ideal y es bastante fácil cambiarlo si luego decide que necesita acceso aleatorio o repetido. En particular, si fuera a procesarlo para hacer una lista, esta última opción es ideal.
actualización:
El método más rápido, con mucho, es
import itertools as it
import operator as op
list(it.starmap(op.sub, it.izip(a[1:], a)))
$ python -mtimeit -s's = [1, 2]*10000' '[x - y for x, y in zip(s[1:], s)]'
100 loops, best of 3: 13.5 msec per loop
$ python -mtimeit -s'import itertools as it; s = [1, 2]*10000' '[x - y for x, y in it.izip(s[1:], s)]'
100 loops, best of 3: 8.4 msec per loop
$ python -mtimeit -s'import itertools as it; import operator as op; s = [1, 2]*10000' 'list(it.starmap(op.sub, it.izip(s[1:], s)))'
100 loops, best of 3: 6.38 msec per loop
en realidad se ven demasiado complicados para un trivial tarea, especialmente teniendo en cuenta la experiencia asumida OP. ¿Cuándo se convirtieron los bucles for-loop normales en algo malo? –
cuando se convirtió en el doble de lento y más pesado de leer que una comprensión. – aaronasterling
Ok, hice un perfil y en este caso no son dos veces más lentos, pero siguen siendo los más lentos por el momento. 16.8 mseg con la misma entrada que la mostrada arriba. y mi punto sobre ellos siendo más cruxtier para leer todavía está en pie. – aaronasterling
El uso de range
está perfectamente bien. Sin embargo, la programación (como las matemáticas) se basa en las abstracciones. Los pares consecutivos [(x0, x1), (x1, x2), ..., (xn-2, xn-1)], se llaman combinaciones de pares, consulte por ejemplo un recipe in the itertools docs. Una vez que tenga esta función en su conjunto de herramientas, se puede escribir:
for x, y in pairwise(xs):
print(y - x)
O, como una expresión del generador:
consecutive_diffs = (y - x for (x, y) in pairwise(xs))
Aquí está el ejemplo de los reciepes itertools:
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)
Lo cual no es muy legible. Si prefiere algo más comprensible y entiende cómo funcionan los generadores, aquí un ejemplo más largo con el mismo resultado:
def pairwise(it):
"""
Walk a list in overlapping pairs.
>>> list(pairwise([0, 1, 2, 3, 4, 5]))
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
"""
it = iter(it)
start = None
while True:
if not start:
start = next(it)
end = next(it)
yield start, end
start = end
def pairwise(iterable):
i = iter(iterable)
while True:
yield next(i), next(i, '')
Debe agregar algunos comentarios al código. – timiTao
Si bien este código puede responder a la pregunta, proporcionar un contexto adicional con respecto a por qué y/o cómo responde este código a la pregunta mejora su valor a largo plazo. –
¿en qué punto se queda atascado? ¿Qué código tienes hasta ahora? –
posible duplicado de [Python - Diferencias entre los elementos de una lista] (http://stackoverflow.com/questions/2400840/python-differences-between-elements-of-a-list) – SilentGhost