Sólo por una alternativa, ¿qué hay de la generalización de la operación iterate/Valor mínimo de una función lambda para que pueda hacer algo como esto:
for i in seq(1, 9, lambda x: x*2):
print i
...
1
2
4
8
Dónde seq
se define a continuación:
#!/bin/python
from timeit import timeit
def seq(a, b, f):
x = a;
while x < b:
yield x
x = f(x)
def testSeq():
l = tuple(seq(1, 100000000, lambda x: x*2))
#print l
def testGen():
l = tuple((2**x for x in range(27)))
#print l
testSeq();
testGen();
print "seq", timeit('testSeq()', 'from __main__ import testSeq', number = 1000000)
print "gen", timeit('testGen()', 'from __main__ import testGen', number = 1000000)
La diferencia en el rendimiento no es mucho:
seq 7.98655080795
gen 6.19856786728
[EDIT]
Para apoyar iteración inversa y con un argumento predeterminado ...
def seq(a, b, f = None):
x = a;
if b > a:
if f == None:
f = lambda x: x+1
while x < b:
yield x
x = f(x)
else:
if f == None:
f = lambda x: x-1
while x > b:
yield x
x = f(x)
for i in seq(8, 0, lambda x: x/2):
print i
Nota: Esto comporta de manera diferente a range
/xrange
en el que la dirección del ensayo <
/>
es elegido por el signo iterador, en lugar de la diferencia entre los valores inicial y final.
su 'for i in range (0,9, -2)' no se repetirá si el primer número es menor que el segundo. – hexparrot
Más exactamente, range() no puede proporcionar una matriz con un paso negativo para un valor positivo. Es un ciclo infinito. – dwerner
@ user1320925 qué quiere estos como los valores de i: 1 2, 4 , 8, 16, 32 .... –