python if-statement comparison match boolean-logic

python - ¿Cómo probar múltiples variables contra un valor?



plot title python (18)

Estoy tratando de hacer una función que compare varias variables con un entero y genere una cadena de tres letras. Me preguntaba si había una manera de traducir esto a Python. Así que di:

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 algo como esto posible?


Creo que esto lo manejará mejor:

my_dict = {0: "c", 1: "d", 2: "e", 3: "f"} def validate(x, y, z): for ele in [x, y, z]: if ele in my_dict.keys(): return my_dict[ele]

Salida:

print validate(0, 8, 9) c print validate(9, 8, 9) None print validate(9, 8, 2) e


Establecer es el buen enfoque aquí, porque ordena las variables, lo que parece ser tu objetivo aquí. {z,y,x} es {0,1,3} cualquiera que sea el orden de los parámetros.

>>> ["cdef"[i] for i in {z,x,y}] [''c'', ''d'', ''f'']

De esta manera, toda la solución es O (n).


Este código puede ser útil

L ={x, y, z} T= ((0,"c"),(1,"d"),(2,"e"),(3,"f"),) List2=[] for t in T : if t[0] in L : List2.append(t[1]) break;


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, te guste. :) Y esta manera es fea.

La otra manera (una mejor) es:

0 in (x, y, z)

Por cierto un montón de if s podría escribirse 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


La forma más mnemotécnica de representar su pseudocódigo en Python sería:

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


Para probar múltiples variables con un solo valor: if 1 in {a,b,c}:

Para probar varios valores con una variable: if a in {1, 2, 3}:


Para verificar si un valor está contenido dentro de un conjunto de variables, puede usar los módulos incorporados itertools y el operator .

Por ejemplo:

Importaciones:

from itertools import repeat from operator import contains

Declarar variables:

x = 0 y = 1 z = 3

Crea mapeo de valores (en el orden que quieras verificar):

check_values = (0, 1, 3)

Usa itertools para permitir la repetición de las variables:

check_vars = repeat((x, y, z))

Finalmente, use la función de map para crear un iterador:

checker = map(contains, check_vars, check_values)

Luego, al verificar los valores (en el orden original), use next() :

if next(checker) # Checks for 0 # Do something pass elif next(checker) # Checks for 1 # Do something pass

etc ...

Esto tiene una ventaja sobre la lambda x: x in (variables) porque el operator es un módulo incorporado y es más rápido y más eficiente que usar lambda que tiene que crear una función personalizada en el lugar.

Otra opción para verificar si hay un valor distinto de cero (o Falso) en una lista:

not (x and y and z)

Equivalente:

not all((x, y, z))


Parece que estás construyendo una especie de cifrado César.

Un enfoque mucho más generalizado es este:

input_values = (0, 1, 3) origo = ord(''c'') [chr(val + origo) for val in inputs]

salidas

[''c'', ''d'', ''f'']

No estoy seguro si es un efecto secundario deseado de su código, pero el orden de su salida siempre se ordenará.

Si esto es lo que quieres, la última línea se puede cambiar a:

sorted([chr(val + origo) for val in inputs])


Puedes usar el diccionario:

x = 0 y = 1 z = 3 list=[] dict = {0: ''c'', 1: ''d'', 2: ''e'', 3: ''f''} if x in dict: list.append(dict[x]) else: pass if y in dict: list.append(dict[y]) else: pass if z in dict: list.append(dict[z]) else: pass print list


Se puede hacer fácilmente como

for value in [var1,var2,var3]: li.append("targetValue")


Si desea utilizar if, else las siguientes afirmaciones son otra solución:

myList = [] aList = [0, 1, 3] for l in aList: if l==0: myList.append(''c'') elif l==1: myList.append(''d'') elif l==2: myList.append(''e'') elif l==3: myList.append(''f'') print(myList)


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

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 probablemente sea MUCHO más complicado que simplemente las declaraciones. Eso es lo que obtienes por tratar de ser más perezoso :)

Una cosa más, tu

if x or y or z == 0:

Se compilará, pero no de la manera que usted quiere. Cuando simplemente pones una variable en una sentencia 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 realiza el comando de verificar una declaración booleana (si no sabes qué es eso, es lo que estás tratando de hacer en tu declaración if en este momento :))

Otra forma perezosa que encontré es:

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


Su problema se resuelve 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]]


Todas las excelentes respuestas proporcionadas aquí se concentran en el requisito específico del póster original y se concentran en la solución if 1 in {x,y,z} presentada por Martijn Pieters.
Lo que ignoran es la implicación más amplia de la pregunta:
¿Cómo pruebo una variable contra múltiples valores?
La solución provista no funcionará para resultados parciales si se usan cadenas, por ejemplo:
Probar si la cadena "Wild" está en múltiples valores

>>> x = "Wild things" >>> y = "throttle it back" >>> z = "in the beginning" >>> if "Wild" in {x, y, z}: print (True) ...

o

>>> x = "Wild things" >>> y = "throttle it back" >>> z = "in the beginning" >>> if "Wild" in [x, y, z]: print (True) ...

para este escenario es más fácil convertir a una cadena

>>> [x, y, z] [''Wild things'', ''throttle it back'', ''in the beginning''] >>> {x, y, z} {''in the beginning'', ''throttle it back'', ''Wild things''} >>> >>> if "Wild" in str([x, y, z]): print (True) ... True >>> if "Wild" in str({x, y, z}): print (True) ... True

Sin embargo, se debe tener en cuenta, como lo menciona @codeforester , que los límites de palabras se pierden con este método, como en:

>>> x=[''Wild things'', ''throttle it back'', ''in the beginning''] >>> if "rot" in str(x): print(True) ... True

las 3 letras de rot existen en combinación en la lista pero no como una palabra individual. Las pruebas de "podredumbre" fallarían, pero si uno de los elementos de la lista fuera "podredumbre en el infierno", también fallaría.
El resultado final es ser cuidadoso con los criterios de búsqueda si utiliza este método y tenga en cuenta que tiene esta limitación.


Una solución de línea:

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

O:

mylist = [''cdef''[i] for i in range(4) if i in (x, y, z)]


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

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

y son evaluados por sí mismos ( False si 0 , True contrario).

Puedes 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}:

usar un set para aprovechar la prueba de membresía de costo constante ( in toma una cantidad fija de tiempo cualquiera que sea el operando de la izquierda).

Cuando usas or , python ve cada lado del operador como expresiones separadas . La expresión x or y == 1 se trata 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 prioridad más baja 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 lugar, esto no haría lo que usted espera que haga.

x or y or z evaluarán el primer argumento que sea "veraz", por ejemplo, no False , numérico 0 o vacío (consulte las expresiones booleanas para obtener información sobre lo que Python considera falso en un contexto booleano).

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

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


Solución anterior: Según lo declarado por Martijn Pieters, el formato correcto y más rápido es:

if 1 in {x, y, z}:

El único problema importante que no parece solucionarse es que desea que su lista de salida incluya cada letra después de una declaración de verdadero si.

Usando solo el consejo de Martijn Pieters, ahora tendrías:

if 0 in {x, y, z}: Mylist.append("c") elif 1 in {x, y, z}: Mylist.append("d") ...

Problema: la primera instrucción if devolvería verdadero, y nunca llegaría a la siguiente instrucción elif. Así que tu lista simplemente regresaría:

["c"]

Lo que quieres es tener sentencias if separadas para que Python lea cada afirmación si las primeras fueron verdaderas o falsas. 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 asigne los números a las letras que desea, y luego simplemente use un bucle ''for'':

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


d = {0:''c'', 1:''d'', 2:''e'', 3: ''f''} x, y, z = (0, 1, 3) print [v for (k,v) in d.items() if x==k or y==k or z==k]