Cómo probar múltiples variables contra un valor

python if-statement comparison match boolean-logic


Estoy tratando de hacer una función que compare múltiples variables con un número entero y produzca una cadena de tres letras.Me preguntaba si había una manera de traducir esto a Python.Digamos:

x = 0
y = 1
z = 3
mylist = []

if x or y or z == 0 :
    mylist.append("c")
if x or y or z == 1 :
    mylist.append("d")
if x or y or z == 2 :
    mylist.append("e")
if x or y or z == 3 : 
    mylist.append("f")

que devolvería una lista de

["c", "d", "f"]

¿Es posible algo así?




Answer 1 Martijn Pieters


No entiendes cómo funcionan las expresiones booleanas;no funcionan como una frase en inglés y supongo que estás hablando de la misma comparación para todos los nombres aquí.Lo que está buscando:

if x == 1 or y == 1 or z == 1:

x e y de lo contrario se evalúan por sí mismos ( False si 0 , True contrario).

Puede acortar eso usando una prueba de contención contra una tupla :

if 1 in (x, y, z):

o mejor aún:

if 1 in {x, y, z}:

usando un set para aprovechar la prueba de membresía de costo constante ( in un tiempo fijo, cualquiera que sea el operando de la izquierda).

Cuando usa or , python ve cada lado del operador como expresiones separadas . La expresión x or y == 1 se trata primero como una prueba booleana para x , luego, si eso es Falso, se prueba la expresión y == 1 .

Esto se debe a la precedencia del operador . El operador or tiene una precedencia menor que la prueba == , por lo que este último se evalúa primero .

Sin embargo, incluso si este no fuera el caso, y la expresión x or y or z == 1 realidad se interpretara como (x or y or z) == 1 , esto no haría lo que espera que haga.

x or y or z evaluarían el primer argumento que es 'verdadero', por ejemplo, no False , numérico 0 o vacío (ver expresiones booleanas para detalles sobre lo que Python considera falso en un contexto booleano).

Entonces para los valores x = 2; y = 1; z = 0 , x or y or z se resolverían a 2 , porque ese es el primer valor verdadero en los argumentos. Entonces 2 == 1 sería False , aunque y == 1 sería True .

Lo mismo se aplicaría a la inversa; probar múltiples valores contra una sola variable; x == 1 or 2 or 3 fallarían por las mismas razones. Use x == 1 or x == 2 or x == 3 o x in {1, 2, 3} .




Answer 2 dansalmo


Su problema se aborda más fácilmente con una estructura de diccionario como:

x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]



Answer 3 ThatGuyRussell


Como dijo Martijn Pieters,el formato correcto y más rápido es:

if 1 in {x, y, z}:

Usando su consejo, ahora tendría declaraciones if separadas para que Python lea cada declaración si las primeras eran True o False . Como:

if 0 in {x, y, z}:
    mylist.append("c")
if 1 in {x, y, z}:
    mylist.append("d")
if 2 in {x, y, z}:
    mylist.append("e")
...

Esto funcionará, pero si se siente cómodo usando diccionarios (vea lo que hice allí), puede limpiar esto haciendo un diccionario inicial que mapee los números a las letras que desee, luego simplemente use un bucle for:

num_to_letters = {0: "c", 1: "d", 2: "e", 3: "f"}
for number in num_to_letters:
    if number in {x, y, z}:
        mylist.append(num_to_letters[number])



Answer 4 akaRem


La forma directa de escribir x or y or z == 0 es

if any(map((lambda value: value == 0), (x,y,z))):
    pass # write your logic.

Pero no creo que te guste.:)Y este camino es feo.

La otra forma (una mejor)es:

0 in (x, y, z)

BTW un montón de if s se podría escribir como algo como esto

my_cases = {
    0: Mylist.append("c"),
    1: Mylist.append("d")
    # ..
}

for key in my_cases:
    if key in (x,y,z):
        my_cases[key]()
        break



Answer 5 ytpillai


Si eres muy,muy perezoso,puedes poner los valores dentro de una matriz.Como por ejemplo

list = []
list.append(x)
list.append(y)
list.append(z)
nums = [add numbers here]
letters = [add corresponding letters here]
for index in range(len(nums)):
    for obj in list:
        if obj == num[index]:
            MyList.append(letters[index])
            break

También puedes poner los números y las letras en un diccionario y hacerlo,pero esto es probablemente MUCHO más complicado que simplemente si las declaraciones.Eso es lo que obtienes por tratar de ser extra perezoso :)

Una cosa más,tu

if x or y or z == 0:

se compilará,pero no de la manera que tú quieres.Cuando simplemente pones una variable en una declaración if (ejemplo)

if b

el programa comprobará si la variable no es nula.Otra forma de escribir la declaración anterior (que tiene más sentido)es

if bool(b)

Bool es una función incorporada en python que básicamente hace el comando de verificar una declaración booleana (Si no sabes lo que es,es lo que estás tratando de hacer en tu declaración if ahora mismo :))

Otro camino perezoso que encontré es..:

if any([x==0, y==0, z==0])