Para bucle con pasos personalizados en python.

Puedo hacer simples para bucles en python como:

for i in range(10): 

Sin embargo, no pude averiguar cómo hacer más complejos, que son realmente fáciles en c ++.

¿Cómo implementarías un bucle for como este en python?

 for(w = n; w > 1; w = w / 2) 

El más cercano que hice hasta ahora es:

 for w in reversed(range(len(list))) 

Primero y principal: Python for bucles no es realmente lo mismo que un bucle de C for . Ellos son para cada bucles en su lugar. Usted itera sobre los elementos de un iterable. range() genera una secuencia iterable de enteros, lo que le permite emular el C más común for caso de uso de bucle.

Sin embargo, la mayoría de las veces no desea utilizar el range() . Deberías recorrer la lista en sí:

 for elem in reversed(some_list): # elem is a list value 

Si tiene que tener un índice, usualmente usa enumerate() para agregarlo al bucle:

 for i, elem in reversed(enumerate(some_list)): # elem is a list value, i is it's index in the list 

Para bucles realmente “funky”, use while crea su propia función de generador:

 def halved_loop(n): while n > 1: yield n n //= 2 for i in halved_loop(10): print i 

para imprimir 10 , 5 , 2 . Puedes extender eso a las secuencias también:

 def halved_loop(sequence): n = -1 while True: try: yield sequence[n] except IndexError: return n *= 2 for elem in halved_loop(['foo', 'bar', 'baz', 'quu', 'spam', 'ham', 'monty', 'python']): print elem 

que imprime:

 python monty spam foo 
 for i in range(0, 10, 2): print(i) >>> 0 >>> 2 >>> 4 >>> 6 >>> 8 

http://docs.python.org/2/library/functions.html

 >>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> range(1, 11) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> range(0, 30, 5) [0, 5, 10, 15, 20, 25] >>> range(0, 10, 3) [0, 3, 6, 9] 

Para su ejemplo exacto, probablemente no usaría un bucle for, sino un bucle while:

 w = n while w > 1: do stuff w = w / 2 

Necesitas usar un generador. Podría implementar esto de la siguiente manera:

 def stepDown(n): while n>1: yield n n = n/2 for i in stepDown(n): print i # or do whatever else you wish. 

Tenga en cuenta que esto se generaliza fácilmente a otros patrones complicados que puede tener en mente.

Algo así como for i in [n/(2**j) for j in range(int(math.log(n))+1)]

Para el caso más general, podría crear una función de generador personalizado, que toma un start , una stop y una función para generar el siguiente paso del último:

 def my_range(start, stop, f): x = start while x < stop if stop > start else x > stop: yield x x = f(x) >>> list(my_range(1, 1024, lambda x: x*2)) [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] >>> list(my_range(1000, 1, lambda x: x/2)) [1000, 500.0, 250.0, 125.0, 62.5, 31.25, 15.625, 7.8125, 3.90625, 1.953125]