Tengo funciones en Python que tienen una serie de declaraciones if .
def some_func(): if condition_1: return result_1 if condition_2: return result_2 ... #other if statements
Pero quiero que el orden de estas declaraciones if cambie cada vez que llamo a la función. Por ejemplo, si llamo a la función, puede haber un caso en el que condition_1
y condition_2
sean verdaderas, pero dado condition_1
se verifica primero, obtendré result_1
pero quiero que cuando llame a la función por segunda vez, se verifique otra condición aleatoria. (ya que solo tengo cinco declaraciones if en la función, por lo tanto, cualquiera de las cinco condiciones).
Entonces, ¿hay alguna forma de hacer esto, como almacenar las condiciones en una lista o algo así?
Cualquier ayuda será apreciada.
Puede crear una lista de condition
y result
y luego shuffle
como se muestra a continuación:
import random def some_func(x): lst_condition_result = [((x>1), True), ((x>2), False)] random.shuffle(lst_condition_result) for condition, result in lst_condition_result: if condition: return result
Producción:
>>> some_func(20) True >>> some_func(20) False >>> some_func(20) False
Si desea mezclar en tiempo de ejecución, coloque sus condiciones y resultados como funciones en una lista de funciones (una vez) y mezcle (cada vez). Luego evalúe esas funciones en ese orden aleatorio hasta que obtenga un valor que no sea falso (suponiendo que las declaraciones de return
siempre devuelvan un valor que no sea falso).
Al momento de escribir, no proporcionaste un ejemplo concreto, así que trabajaré con este:
def odd_or_multipleof3(n): if n % 2: return "odd" if n % 3 == 0: return "multiple of 3" return "neither"
Aquí odd_or_multipleof3(9)
devolverá "impar", pero cuando se intercambien los bloques if
, devolverá "múltiplo de 3". Para permitir que la evaluación de los bloques se realice en un orden aleatorio, de modo que pueda obtener cualquiera de estos valores de retorno, puede hacer lo siguiente:
from random import shuffle funcs = [ lambda n: "odd" if n % 2 else None, lambda n: "multiple of 3" if n % 3 == 0 else None ] def odd_or_multipleof3(n): shuffle(funcs) return any((result := func(n)) for func in funcs) and result print(odd_or_multipleof3(9))
Esta forma de trabajar garantizará que las condiciones solo se evalúen mientras no devuelvan un valor verdadero, no más.
Este solo evalúa tanto como sea necesario, es decir, tanto como lo harían las sentencias if mezcladas literalmente:
def some_func(): conditions_and_results = [ (lambda: condition_1, lambda: result_1), (lambda: condition_2, lambda: result_2), ... ] random.shuffle(conditions_and_results) for condition, result in conditions_and_results: if condition(): return result()
O de manera más eficiente (al menos para listas grandes), reutilizando la misma lista cada vez y solo barajando tanto como sea necesario:
ifs = [ (lambda: condition_1, lambda: result_1), (lambda: condition_2, lambda: result_2), ... ] def some_func(): for i, if_i in enumerate(ifs): j = random.randrange(i, len(ifs)) condition, result = ifs[i] = ifs[j] ifs[j] = if_i if condition(): return result()
Demostración ( ¡Pruébelo en línea! ):
import random ifs = [ (lambda: x > 0, lambda: '> 0'), (lambda: x > 1, lambda: '> 1'), (lambda: x > 2, lambda: '> 2'), (lambda: x > 3, lambda: '> 3'), ] def some_func(): for i, if_i in enumerate(ifs): j = random.randrange(i, len(ifs)) condition, result = ifs[i] = ifs[j] ifs[j] = if_i if condition(): return result() x = 2 print([some_func() for _ in range(10)])
Salida de muestra:
['> 1', '> 0', '> 1', '> 0', '> 0', '> 0', '> 0', '> 1', '> 0', '> 0']