Estoy tratando de hacer una función que compare múltiples variables con un número 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 posible algo así?
Aquí hay una forma más de hacerlo:
x = 0 y = 1 z = 3 mylist = [] if any(i in [0] for i in[x,y,z]): mylist.append("c") if any(i in [1] for i in[x,y,z]): mylist.append("d") if any(i in [2] for i in[x,y,z]): mylist.append("e") if any(i in [3] for i in[x,y,z]): mylist.append("f")Es una mezcla de comprensión de lista y cualquier palabra clave.
puedes desarrollarlo de dos maneras
def compareVariables(x,y,z): mylist = [] if x==0 or y==0 or z==0: mylist.append('c') if x==1 or y==1 or z==1: mylist.append('d') if x==2 or y==2 or z==2: mylist.append('e') if x==3 or y==3 or z==3: mylist.append('f') else: print("wrong input value!") print('first:',mylist) compareVariables(1, 3, 2)O
def compareVariables(x,y,z): mylist = [] 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') if 3 in (x,y,z): mylist.append('f') else: print("wrong input value!") print('second:',mylist) compareVariables(1, 3, 2)Puedes unir esto
x = 0 y = 1 z = 3en una variable.
In [1]: xyz = (0,1,3,) In [2]: mylist = []Cambiar nuestras condiciones como:
In [3]: if 0 in xyz: ...: mylist.append("c") ...: if 1 in xyz: ...: mylist.append("d") ...: if 2 in xyz: ...: mylist.append("e") ...: if 3 in xyz: ...: mylist.append("f")Producción:
In [21]: mylist Out[21]: ['c', 'd', 'f']El or no funciona así, como se explica en esta respuesta .
Si bien la respuesta genérica sería usar
if 0 in (x, y, z): ...este no es el mejor para el problema específico . En tu caso estás haciendo pruebas repetidas , por lo que vale la pena componer un conjunto de estas variables:
values = {x, y, z} if 0 in values: mylist.append("c") if 1 in values: mylist.append("d")Podemos simplificar esto usando un diccionario; esto dará como resultado los mismos valores:
mappings = {0: "c", 1: "d", ...} for k in mappings: if k in values: mylist.append(mappings[k]) O si el orden de mylist es arbitrario, puede recorrer los valores en su lugar y hacerlos coincidir con las asignaciones:
mappings = {0: "c", 1: "d", ...} for v in (x, y, z): if v in mappings: mylist.append(mappings[v])Esto te ayudara.
def test_fun(val): x = 0 y = 1 z = 2 myList = [] if val in (x, y, z) and val == 0: myList.append("C") if val in (x, y, z) and val == 1: myList.append("D") if val in (x, y, z) and val == 2: myList.append("E") test_fun(2);Puede probar el método que se muestra a continuación. En este método, tendrá la libertad de especificar/ingresar el número de variables que desea ingresar.
mydict = {0:"c", 1:"d", 2:"e", 3:"f"} mylist= [] num_var = int(raw_input("How many variables? ")) #Enter 3 when asked for input. for i in range(num_var): ''' Enter 0 as first input, 1 as second input and 3 as third input.''' globals()['var'+str('i').zfill(3)] = int(raw_input("Enter an integer between 0 and 3 ")) mylist += mydict[globals()['var'+str('i').zfill(3)]] print mylist >>> ['c', 'd', 'f']Tal vez necesite una fórmula directa para establecer los bits de salida.
x=0 or y=0 or z=0 is equivalent to x*y*z = 0 x=1 or y=1 or z=1 is equivalent to (x-1)*(y-1)*(z-1)=0 x=2 or y=2 or z=2 is equivalent to (x-2)*(y-2)*(z-2)=0 Mapeemos a bits: 'c':1 'd':0xb10 'e':0xb100 'f':0xb1000
Relación de isc (es 'c'):
if xyz=0 then isc=1 else isc=0Usar fórmula matemática si https://youtu.be/KAdKCgBGK0k?list=PLnI9xbPdZUAmUL8htSl6vToPQRRN3hhFp&t=315
[c]: (xyz=0 and isc=1) or (((xyz=0 and isc=1) or (isc=0)) and (isc=0))
[d]: ((x-1)(y-1)(z-1)=0 and isc=2) or (((xyz=0 and isd=2) or (isc=0)) and (isc=0))
...
Conecte estas fórmulas siguiendo la lógica:
and es la suma de los cuadrados de las ecuacionesor es el producto de ecuacionesy tendrás una ecuación total suma expresa y tienes fórmula total de suma
entonces sum&1 es c, sum&2 es d, sum&4 es e, sum&5 es f
Después de esto, puede formar una matriz predefinida donde el índice de los elementos de la cadena correspondería a la cadena lista.
array[sum] te da la cadena.
Se puede hacer fácilmente como
for value in [var1,var2,var3]: li.append("targetValue")Mientras que el patrón para probar múltiples valores
>>> 2 in {1, 2, 3} True >>> 5 in {1, 2, 3} Falsees muy legible y funciona en muchas situaciones, hay una trampa:
>>> 0 in {True, False} Truepero queremos tener
>>> (0 is True) or (0 is False) FalseUna generalización de la expresión anterior se basa en la respuesta de ytpillai :
>>> any([0 is True, 0 is False]) Falseque se puede escribir como
>>> any(0 is item for item in (True, False)) FalseSi bien esta expresión devuelve el resultado correcto, no es tan legible como la primera expresión :-(
Sin dict, prueba esta solución:
x, y, z = 0, 1, 3 offset = ord('c') [chr(i + offset) for i in (x,y,z)]y da:
['c', 'd', 'f']No entiendes cómo funcionan las expresiones booleanas; no funcionan como una oración en inglés y supongo que está hablando de la misma comparación para todos los nombres aquí. Estás buscando:
if x == 1 or y == 1 or z == 1: x e y se evalúan por sí solos ( False si es 0 , True en caso 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}: usar un set para aprovechar la prueba de membresía de costo constante (es decir in toma una cantidad de tiempo fija 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 esta última se evalúa primero .
Sin embargo, incluso si este no fuera el caso, y la expresión x or y or z == 1 en realidad se interpretara como (x or y or z) == 1 en su lugar, esto aún no haría lo que espera que haga.
x or y or z se evaluaría como el primer argumento que es 'veraz', por ejemplo, no False , numérico 0 o vacío (consulte las expresiones booleanas para obtener 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ía en 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ía por las mismas razones. Usa x == 1 or x == 2 or x == 3 o x in {1, 2, 3} .
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]Producción:
print validate(0, 8, 9) c print validate(9, 8, 9) None print validate(9, 8, 2) ed = {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]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 de esta manera es feo.
La otra forma (una mejor) es:
0 in (x, y, z) Por cierto, muchos if s podrían 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]() breakSu 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]]Para verificar si un valor está contenido dentro de un conjunto de variables, puede usar los módulos integrados itertools y operator .
Por ejemplo:
Importaciones:
from itertools import repeat from operator import containsDeclarar variables:
x = 0 y = 1 z = 3Cree un mapeo de valores (en el orden que desee verificar):
check_values = (0, 1, 3) Use itertools para permitir la repetición de las variables:
check_vars = repeat((x, y, z)) Finalmente, use la función 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 passetc...
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 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))Si desea usar if, else, las siguientes declaraciones 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. Tal 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]) breakTambién puede poner los números y las letras en un diccionario y hacerlo, pero esto probablemente sea MUCHO más complicado que simplemente declaraciones condicionales. Eso es lo que obtienes por tratar de ser más perezoso :)
Una cosa más, tu
if x or y or z == 0:compilará, pero no de la manera que usted desea. Cuando simplemente coloca una variable en una declaración if (ejemplo)
if bel 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 sabe qué es eso, es lo que está tratando de hacer en su declaración if en este momento :))
Otra forma perezosa que encontré es:
if any([x==0, y==0, z==0])Establecer es el buen enfoque aquí, porque ordena las variables, lo que parece ser su objetivo aquí. {z,y,x} es {0,1,3} sea cual sea el orden de los parámetros.
>>> ["cdef"[i] for i in {z,x,y}] ['c', 'd', 'f']De esta forma, la solución completa 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;Como afirma 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, ya sea que la primera sea True o False . Tal 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:
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])Todas las excelentes respuestas proporcionadas aquí se concentran en el requisito específico del cartel 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 aciertos parciales si usa cadenas, por ejemplo:
Pruebe si la cadena "Wild" tiene varios 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, debe tenerse en cuenta, como lo menciona @codeforester , que los límites de las 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 rot existen en combinación en la lista pero no como una palabra individual. La prueba de "podredumbre" fallaría, pero si uno de los elementos de la lista fuera "podredumbre en el infierno", eso también fallaría.
El resultado es que tenga cuidado con sus criterios de búsqueda si usa este método y tenga en cuenta que tiene esta limitación.
Solución de una 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)]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 listLa forma más pitónica 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")Parece que estás construyendo algún tipo 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 de si es un efecto secundario deseado de su código, pero el orden de su salida siempre se ordenará.
Si esto es lo que desea, la línea final se puede cambiar a:
sorted([chr(val + origo) for val in inputs])Para probar múltiples variables con un solo valor: if 1 in {a,b,c}:
Para probar múltiples valores con una variable: if a in {1, 2, 3}:
uso sin si ejemplo:
x,y,z = 0,1,3 values = {0:"c",1:"d",2:"e",3:"f"} # => as if usage my_list = [values[i] for i in (x,y,z)] print(my_list)