¿Cuál es la diferencia entre “while 1” y “while True”?

He visto dos formas de crear un bucle infinito en Python:

  1. while 1: do_something() 
  2.  while True: do_something() 

¿Hay alguna diferencia entre estos? ¿Es una pythonica más que la otra?

Fundamentalmente, no importa, tales detalles no afectan realmente si algo es “pythonico” o no.

Si estás interesado en trivia sin embargo, hay algunas diferencias.

  1. El tipo booleano incorporado no existía hasta Python 2.3, por lo que el código destinado a ejecutarse en versiones antiguas tiende a usar el formulario while 1: Lo verás en la biblioteca estándar, por ejemplo.

  2. Las incorporaciones True y False no son palabras reservadas antes de Python 3, por lo que podrían asignarse a, cambiando su valor. Esto ayuda con el caso anterior porque el código podría hacer True = 1 para la compatibilidad con versiones anteriores, pero significa que el nombre True debe buscarse en el diccionario global cada vez que se usa.

  3. Debido a la restricción anterior, el código de bytes al que se comstackn las dos versiones es diferente en Python 2, ya que hay una optimización para enteros constantes que no puede usar para True . Como Python puede decir al comstackr el 1 que siempre es distinto de cero, elimina el salto condicional y no carga la constante en absoluto:

     >>> import dis >>> def while_1(): ... while 1: ... pass ... >>> def while_true(): ... while True: ... pass ... >>> dis.dis(while_1) 2 0 SETUP_LOOP 5 (to 8) 3 >> 3 JUMP_ABSOLUTE 3 6 POP_TOP 7 POP_BLOCK >> 8 LOAD_CONST 0 (None) 11 RETURN_VALUE >>> dis.dis(while_true) 2 0 SETUP_LOOP 12 (to 15) >> 3 LOAD_GLOBAL 0 (True) 6 JUMP_IF_FALSE 4 (to 13) 9 POP_TOP 3 10 JUMP_ABSOLUTE 3 >> 13 POP_TOP 14 POP_BLOCK >> 15 LOAD_CONST 0 (None) 18 RETURN_VALUE 

Entonces, while True: es un poco más fácil de leer, y while 1: es un poco más amable con las versiones anteriores de Python. Como es poco probable que necesite ejecutar Python 2.2 en estos días o que deba preocuparse por el recuento de bytecode de sus bucles, el primero es marginalmente preferible.

La forma más python siempre será la más legible. Usar while True:

Realmente no importa Tampoco es difícil de leer o entender, aunque personalmente siempre lo usaría while True , que es un poco más explícito.

Más en general, un montón de ciclos de interrupción de tiempo mientras que las personas escriben en Python podrían ser otra cosa. A veces veo que la gente escribe i = 0; while True: i += 1 ... i = 0; while True: i += 1 ... , que se puede reemplazar con for i in itertools.count() y las personas que escriben while True: foo = fun() if foo is None: break cuando esto se puede escribir for foo in iter(fun, None) , que requiere aprendizaje pero tiene menos repetición y más oportunidades para cometer errores tontos.

Ninguno.

Ambos significan que tengo que escanear el código buscando el break , en lugar de poder ver la condición de parada donde corresponde.

Intento evitar este tipo de cosas siempre que sea posible, y si no es posible, deje que el código hable por sí mismo de la siguiente manera:

 while not found_answer: check_number += 1 if check_number == 42: found_answer = True 

Edit: Parece que la palabra “evitar” arriba no era lo suficientemente clara. Usualmente, se debe evitar por completo el uso de un bucle básicamente infinito y dejarlo en algún lugar dentro del bucle (usar break ). A veces eso no es posible. En ese caso, me gusta usar algo como el código anterior, que, sin embargo, todavía representa el mismo concepto ( el código anterior no es más que un compromiso) , pero al menos puedo mostrar el propósito del bucle al principio : al igual que yo no llamaría una función do_something_with_args(*args) .

Creo que esto es sobre todo una cuestión de estilo. Ambos deben ser fácilmente comprensibles como un bucle infinito.

Sin embargo, personalmente prefiero la segunda opción. Esto se debe a que solo se necesita un micro paso mental menos para comprender, especialmente para los progtwigdores sin fondo en C.

La primera funcionará también en aquellas versiones anteriores donde True aún no está definido.

Si tiene un algoritmo que se supone que termina en un tiempo finito, le recomendaría esto, que siempre es más seguro que en while True :

 maxiter = 1000 for i in xrange(maxiter): # your code # on success: break else: # that algorithm has not finished in maxiter steps! do something accordingly 

OMI la segunda opción es más obvia .

Si pudieras deshacerte del while y escribir un código más compacto, eso podría ser más pythonico.
Por ejemplo:

 # Get the even numbers in the range 1..10 # Version 1 l = [] n = 1 while 1: if n % 2 == 0: l.append(n) n += 1 if n > 10: break print l # Version 2 print [i for i in range(1, 11) if i % 2 == 0] # Version 3 print range(2, 11, 2) 

Creo que la segunda expresión es más explícita, y por lo tanto más python .

Esto es solo una cuestión de estilo, cualquier principiante de progtwigción entenderá cualquiera de las opciones.

Pero la segunda opción solo funcionará si True no fue asignado a False , lo que fue posible hasta Python 3:

 >>> True = False >>> True False 

La mejor manera es “while True” con una ruptura condicional del bucle.