Todavía soy relativamente nuevo en Python y he estado usando declaraciones como las siguientes:

flag = False
while flag == False:
    # Do something here that might set the flag to True,
    flag = True

Sin embargo, esto podría escribirse así:

while not flag:
    # Do something...
    flag = True 
while flag is False:
    # Do something...
    flag = True

Con una forma adicional (¿preferida?) De escribir este tipo de bucle:

while True:
    # Do something and if wanting wanting to break out of loop,
    break

Los primeros tres métodos son más explícitos, entonces ¿por qué no se prefieren ellos (o uno de ellos) sobre el cuarto método? ¿Hay alguna diferencia entre las tres primeras formas de escribir el "while flag == False"?

0
Lotte 13 may. 2016 a las 02:38

4 respuestas

La mejor respuesta

Todas ellas son técnicamente diferentes.

Ejemplo 1

Supongamos que tiene una llamada de función que no devuelve nada significativo, de la siguiente manera:

def fun(x=None):
    return x

Ahora, para sus bucles while, todos los cuales se definirán de la siguiente manera:

def while1():
   flag = False
   while flag == False:
      flag = fun(None)

def while2():
   flag = False
   while flag is False:
      flag = fun(None)

def while3():
   flag = False
   while not flag:
      flag = fun(None)

En este caso, solo while1 y while2 terminarán. Como bool(None) se evalúa como False, while3 continuará infinitamente, pero como None != False y None is not False, tanto while1 como while2 Terminar.

Ahora, esto se vuelve más interesante con ejemplos más complicados.

Ejemplo 2

def fun(x):
    return x

Ahora, para cada uno de nuestros bucles, vamos a cambiar flag = fun() a flag = fun(0).

En este caso, while1 y while3 terminan, mientras que while2 continúa indefinidamente. Esto se debe a que bool(0) == False y 0 == False, pero 0 is not False.

Ejemplo 3 - Mutables

Ahora, esto se vuelve mucho más complicado con las mutables, por lo que lo explícito frente a lo implícito depende de una situación a otra. Las mutables son cualquier objeto que se pueda modificar e incluyen dictados, listas. Los objetos inmutables son cualquier cosa que no se pueda modificar, como tuplas, ints, flotantes, strs.

Digamos que tengo lo siguiente:

a = []
b = []

En este caso, bool(a) == False y a == b, pero a is not b. En resumen, no existe una regla simple y firme sobre cómo verificar los valores de falsey o truthey.

Sin embargo, hay reglas generales.

Reglas generales

Sin marcar ninguno versus otro Si acepta cualquier valor que no sea Ninguno, marque x is None.

Comprobando mutables Nunca use x is b, ya que los mutables pueden tener diferentes ID, a menos que desee verificar explícitamente un objeto con el mismo ID (id(x) == id(b). Por lo general, marque not x o x == b

>>> a = []
>>> b = []
>>> a is b
False
>>> a == b
True
>>> not a
True

Comprobando strs, flotantes e ints Para strs, flotantes y entrantes, siempre marque x == b y no x is b. Esto se debe a que para cadenas cortas, flotantes, entradas, los resultados pueden ser verdaderos si x == b, pero para casos más complicados, su código dejará de funcionar.

Por ejemplo:

>>> a = 1
>>> a is 1
True
>>> a = 10000000
>>> a is 10000000
False

Comprobación de booleanos

Para los booleanos, puede hacer cualquiera de los anteriores, pero not x es preferible a x == b o x is b.

Finalmente ... Mientras bucles

Si puede, siempre convierta un ciclo while en un ciclo for. Esto no siempre es posible, pero digamos que desea hacer un caso simple:

x = 0
while x < 10:
    print(x)
    x -= 1

Esto se puede convertir a:

for x in range(10):
    print(x)

La razón para usar bucles for en lugar de bucles while es si se produce algún error en su código, mientras que los bucles pueden conducir a un bucle indefinido y bloquear su programa, mientras que un bucle for siempre saldrá.

0
Alexander Huszagh 13 may. 2016 a las 00:33

Creo que la sintaxis while True: está bien para la lógica simple. Una vez que comienzas a salir del bucle desde múltiples ubicaciones o necesitas rastrear si el bucle fue exitoso, entonces puede ser complicado.

Además, si la condición while se nombra correctamente, entonces documenta los motivos por los que realiza un bucle.

while not end_of_file:
   ..read read read..

Evitando la declaración break en bucle, en mi humilde opinión, hace que el código sea más legible. Al igual que evitar múltiples declaraciones return en una función.

0
swdev 13 may. 2016 a las 00:01

No creo que haya una preferencia realmente. Un ciclo while continuará ejecutando el bloque de código siempre que la expresión booleana especificada permanezca Verdadero.

Flag == True, not Flag, i <6 o evalúen expresiones booleanas. Si solo dices mientras True como en tu ejemplo, solo ingresarás un bucle infinito. Eso responde tu pregunta?

0
masterforker 12 may. 2016 a las 23:44

Mientras que los tres primeros son más explícitos, el último es más legible y claro. Esto diría que la convierte en la mejor opción por encima de las otras tres. No se buscará la inicialización de alguna variable para el bucle. Dicho esto, todos los métodos son perfectamente aceptables y debe usar el que le resulte más cómodo.

0
theaustinseven 12 may. 2016 a las 23:44