¿Tiene condiciones de bucle extra mientras … basado en una condición?

La variable a puede tomar cualquier número de valores. El valor de a es la cantidad de condiciones predefinidas adicionales que se deben tener para el bucle while.

Esto se puede hacer con varias declaraciones elif , pero ¿hay una forma más limpia de hacerlo?

 if a == 0: while condition_1: ... elif a == 1: while condition_1 or condition_2: ... elif a == 2: while condition_1 or condition_2 or condition_3: ... 

Una forma general de hacer lo que otros idiomas hacen con una instrucción de switch es crear un diccionario que contenga una función para cada uno de sus casos:

 conds = { 0: lambda: condition_1, 1: lambda: condition_1 or condition_2, 2: lambda: condition_1 or condition_2 or condition_3 } 

Entonces:

 while conds[a](): # do stuff 

Al usar lambdas (o funciones nombradas si sus condiciones son particularmente complejas), la condición apropiada se puede evaluar cada vez a través del bucle, en lugar de una vez cuando se define el diccionario.

En este caso simple donde su a tiene valores enteros secuenciales que comienzan en 0, puede usar una lista y guardar un poco de escritura. Para simplificar aún más, puede definir cada una de sus condiciones en términos de la anterior, ya que solo está agregando una condición cada vez:

 conds = [ lambda: condition_1, lambda: conds[0]() or condition_2, lambda: conds[1]() or condition_3 ] 

O, como lo sugiere Julien en un comentario:

 conds = [ lambda: condition_1, lambda: condition_2, lambda: condition_3 ] while any(cond() for cond in conds[:a+1]): # do stuff 

Has intentado algo como ésto:

 while (a >= 0 and condition_1) or (a >= 1 and condition_2) or (a >= 2 and condition_3) ... 

Podría definir una función para evaluar while :

 def test(a): if a == 1: return condition1(...) elif a == 2: return condition2(...) or condition1(...) elif a == 3: return condition2(...) or condition1(...) or condition3(...) else: return False # test(a) will check the conditions ... define additional arguments if you need them while test(a): do_stuff 

Todavía tiene los elifs pero no necesita escribir el while -loop varias veces.