2010-09-10 26 views
32

Me preguntaba si es posible llevar a cabo un cierto número de operaciones sin almacenar el número de iteración de bucle en cualquier lugar.iterar un cierto número de veces sin almacenar el número de iteración en cualquier lugar

Por ejemplo, digamos que quiero imprimir dos "hello" mensajes a la consola. Ahora sé que puedo hacer:

for i in range(2): 
    print "hello" 

pero entonces la variable i va a tomar los valores 0 y 1 (que realmente no lo necesito). ¿Hay alguna forma de lograr lo mismo sin almacenar esos valores no deseados en ninguna parte?

Respuesta

40

El idioma (compartida por un buen número de otros idiomas) para una variable no utilizada es un solo subrayado _. Los analizadores de código normalmente no se quejan de que _ no se utilizan, y los programadores sabrán instantáneamente que es un atajo para i_dont_care_wtf_you_put_here. No hay forma de iterar sin tener una variable de elemento, como dice el Zen de Python, "los casos especiales no son lo suficientemente especiales como para romper las reglas".

+2

No entiendo por qué una cosa tal como AutoHotkey '' Loop, 5 {... '(simplemente repite una acción 5 veces) no existe en ningún otro lado. No se requieren variables y proporciona una mejor legibilidad. – Blauhirn

+0

_ también se usa para '' 'gettext''' i18n y su variable predefinida por el intérprete. '' 'i''' se ve mucho mejor – ubombi

0
for word in ['hello'] * 2: 
    print word 

No es Python idiomática, pero tampoco es lo que estás tratando de hacer.

+0

Por ejemplo, necesita una variable no utilizada para generar una lista de números aleatorios. – wRAR

+0

El problema es que la variable no está en uso. Alguien tiene que hacer un seguimiento de cuántas veces para iterar, y cuántas veces se ha ejecutado el bucle. – nmichaels

+0

@Nathon: Incorrecto. Dado que 'for i in seq: stuff()' es equivalente a (perdóneme las llaves, pero los comentarios no previenen las nuevas líneas) '_iterator = iter (seq); while True {try {i = next (_iterator)} excepto StopIteration {break} stuff()} ', podríamos eliminar la parte' i = 'de la versión desacralizada y terminar sin variable de iteración. Todo el estado de iteración es gestionado por el iterador, no por la variable de iteración. – delnan

10
exec 'print "hello";' * 2 

debería funcionar, pero estoy un poco avergonzado de haberlo pensado.

Actualización: acaba de ocurrir otra:

for _ in " "*10: print "hello" 
+0

+1 por su honestidad ;-) – nicorellius

3

Aunque estoy completamente de acuerdo con la respuesta de delnan, no es imposible:

loop = range(NUM_ITERATIONS+1) 
while loop.pop(): 
    do_stuff() 

Nótese, sin embargo, que esto no va a funcionar para una lista arbitraria: si el primer valor de la lista (el último apareció) no evalúa a False, recibirá otra iteración y una excepción en el siguiente paso: IndexError: pop from empty list. Además, su lista (loop) estará vacía después del ciclo.

Sólo por curiosidad. ;)

0

Lo sentimos, pero para iterar sobre cualquier cosa en cualquier idioma, Python y Inglés incluido, un índice debe almacenar. Ya sea en una variable o no. Encontrar una forma de ocultar el hecho de que python está rastreando internamente el bucle for no cambiará el hecho de que sí lo está. Yo recomendaría simplemente dejarlo como está.

6

Bueno, creo que el forloop que ha proporcionado en la pregunta es casi tan bueno como puede ser, pero quiero señalar que las variables no utilizadas que tienen que asignarse se pueden asignar a la variable llamada _, una convención para "descartando" el valor asignado. Aunque la referencia _ mantendrá el valor que le asignó, los diseñadores de código y otros desarrolladores comprenderán que no está utilizando esa referencia. Así que aquí está un ejemplo:

for _ in range(2): 
    print('Hello') 
-1

Resulta que el uso ficticio * (palabra que empiece es ficticio) como una variable de hacer el mismo truco que _. Pero no te metas con una variable ya definida o algunas veces utilizada o una función.

3

Otros han abordado la imposibilidad de evitar completamente una variable de iteración en un bucle for, pero hay opciones para reducir el trabajo una pequeña cantidad. range tiene que generar un montón de números después de todo, lo que implica una pequeña cantidad de trabajo; si se quiere evitar incluso que, puede utilizar itertools.repeat que acaba de obtener el mismo valor (ignorado) de nuevo una y otra vez, que no implica la creación/recuperación de diferentes objetos:

from itertools import repeat 

for _ in repeat(None, 200): # Runs the loop 200 times 
    ... 

Esto funcionará más rápido en microbenchmarks que for _ in range(200):, pero si el cuerpo del lazo hace un trabajo significativo, es una gota en el cubo. Y a diferencia de multiplicar alguna secuencia anónima para su ciclo iterable, repeat tiene solo un costo de configuración trivial, sin sobrecarga de memoria en función de la longitud.

0

Esto imprimirá 'hola' 3 veces sin almacenar i ...

[print('hello') for i in range(3)] 
+2

Esto es lo mismo que el código original de OP, simplemente presentado como una lista de comprensión en lugar de un ciclo for. –

+0

Creo que 'i' no existirá fuera de la lista de comprensión, que es diferente del for loop –

0

Usted puede simplemente hacer
impresión 2 * 'hola'

+1

Esa es una solución solo para el _example_ OP que proporciona. No responde a todas las instancias. – Nae

Cuestiones relacionadas