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í?
python
if-statement
comparison
match
boolean-logic
usuario1877442
fuente
fuente
1
en (tupla)any
/all
funciones. Por ejemplo:all([1, 2, 3, 4, False])
devolverá Falseall([True, 1, 2, 3])
devolverá Trueany([False, 0, 0, False])
devolverá Falseany([False, 0, True, False])
devolverá Trueif x == 0 or 1:
, que por supuesto es similarif x or y == 0:
, pero puede ser un poco confuso para los novatos. Dado el gran volumen de "¿Por qué no estoyx == 0 or 1
trabajando?" preguntas, preferiría usar esta pregunta como nuestro objetivo duplicado canónico para estas preguntas.0
,0.0
oFalse
. Puede escribir fácilmente un código incorrecto que da la respuesta "correcta".Respuestas:
No comprende 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:
x
y dey
lo contrario se evalúan por su cuenta (False
si0
, de loTrue
contrario).Puede acortar eso usando una prueba de contención contra una tupla :
o mejor aún:
usando a
set
para aprovechar la prueba de membresía de costo constante (in
toma una cantidad fija de tiempo, sea cual sea el operando de la izquierda).Cuando lo usa
or
, python ve cada lado del operador como expresiones separadas . La expresiónx or y == 1
se trata primero como una prueba booleanax
, luego, si eso es falso,y == 1
se prueba la expresión .Esto se debe a la precedencia del operador . El
or
operador tiene una precedencia 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 en
x or y or z == 1
realidad se interpretara en su(x or y or z) == 1
lugar, esto todavía no haría lo que espera que haga.x or y or z
evaluaría el primer argumento que es 'verdadero', por ejemplo, noFalse
, 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ía2
, porque ese es el primer valor verdadero en los argumentos. Entonces2 == 1
seríaFalse
, aunquey == 1
seríaTrue
.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. Usex == 1 or x == 2 or x == 3
ox in {1, 2, 3}
.fuente
set
versión. Las tuplas son muy baratas de crear e iterar. Al menos en mi máquina, las tuplas son más rápidas que las series siempre que el tamaño de la tupla sea de alrededor de 4-8 elementos. Si tiene que escanear más que eso, use un conjunto, pero si está buscando un elemento de entre 2 y 4 posibilidades, ¡una tupla es aún más rápida! Si se puede organizar para el caso más probable que sea por primera vez en la tupla, la victoria es aún más grande: (mi prueba:timeit.timeit('0 in {seq}'.format(seq=tuple(range(9, -1, -1))))
)set
notación literal para esta prueba no es un ahorro a menos que el contenido delset
literal también sea literal, ¿verdad?if 1 in {x, y, z}:
no puede almacenar en cachéset
, porquex
,y
yz
podría cambiar, por lo que cualquiera de las soluciones necesita construir unatuple
oset
desde cero, y sospecho que cualquier ahorro de búsqueda que pueda obtener al verificar la membresía se verá afectado por un mayorset
tiempo de creación.in [...]
oin {...}
) solo funciona si los contenidos de la lista o conjunto también son literales inmutables.Su problema se aborda más fácilmente con una estructura de diccionario como:
fuente
d = "cdef"
que lleva aMyList = ["cdef"[k] for k in [x, y, z]]
map(lambda i: 'cdef'[i], [x, y, z])
[x, y, z]
Como afirmó Martijn Pieters, el formato correcto y más rápido es:
Usando su consejo, ahora tendría declaraciones if separadas para que Python lea cada declaración si las anteriores eran
True
oFalse
. Como: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 desee, luego simplemente use un bucle for:
fuente
La forma directa de escribir
x or y or z == 0
esPero no creo que te guste. :) Y de esta manera es feo.
La otra forma (mejor) es:
Por cierto, muchos
if
s podrían escribirse como algo asífuente
dict
lugar de una clave, obtendrá errores porque el valor de retorno de.append
esNone
, y al llamarNone
da unAttributeError
. Sin embargo, en general estoy de acuerdo con este método.filter
, sería mejor quemap
, ya que solo devolverá instancias en las que lambda se evalúe como verdaderoany(v == 0 for v in (x, y, z))
Si eres muy muy vago, puedes poner los valores dentro de una matriz. Como
También puede poner los números y letras en un diccionario y hacerlo, pero esto es probablemente MUCHO más complicado que simplemente las declaraciones if. Eso es lo que obtienes por tratar de ser más vago :)
Una cosa más, tu
se compilará, pero no de la manera que desea. Cuando simplemente pones una variable en una declaración if (ejemplo)
el programa verificará si la variable no es nula. Otra forma de escribir la declaración anterior (que tiene más sentido) es
Bool es una función incorporada en python que básicamente hace 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:
fuente
list
es un Python incorporado; use otro nombre en su lugar, comoxyz
por ejemplo. ¿Por qué construyes la lista en cuatro pasos cuando puedes hacer uno, es decirxyz = [x, y, z]
? No use listas paralelas, use un dict en su lugar. En general, esta solución es mucho más complicada que la de ThatGuyRussell . También para la última parte, ¿por qué no hacer una comprensión, es decirany(v == 0 for v in (x, y, z))
? También las matrices son algo más en Python.Para verificar si un valor está contenido dentro de un conjunto de variables, puede usar los módulos incorporados
itertools
yoperator
.Por ejemplo:
Importaciones:
Declarar variables:
Cree una asignación de valores (en el orden que desea verificar):
Use
itertools
para permitir la repetición de las variables:Finalmente, use la
map
función para crear un iterador:Luego, al verificar los valores (en el orden original), use
next()
:etc ...
Esto tiene una ventaja sobre el
lambda x: x in (variables)
porqueoperator
es un módulo incorporado y es más rápido y más eficiente que usar ellambda
que tiene que crear una función in situ personalizada.Otra opción para verificar si hay un valor distinto de cero (o Falso) en una lista:
Equivalente:
fuente
Establecer es el buen enfoque aquí, porque ordena las variables, lo que parece ser su objetivo aquí.
{z,y,x}
es{0,1,3}
cualquiera que sea el orden de los parámetros.De esta manera, toda la solución es O (n).
fuente
Todas las excelentes respuestas proporcionadas aquí se concentran en los requisitos específicos del póster original y se concentran en la
if 1 in {x,y,z}
solución presentada por Martijn Pieters.Lo que ignoran es la implicación más amplia de la pregunta:
¿cómo pruebo una variable contra varios valores?
La solución provista no funcionará para los accesos parciales si se usan cadenas, por ejemplo:
Pruebe si la cadena "Wild" tiene varios valores
o
para este escenario, es más fácil convertir a una cadena
Sin embargo, debe tenerse en cuenta, como se mencionó anteriormente
@codeforester
, que los límites de palabras se pierden con este método, como en:las 3 letras
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", también fallaría.En resumen, tenga cuidado con sus criterios de búsqueda si usa este método y tenga en cuenta que tiene esta limitación.
fuente
Creo que esto lo manejará mejor:
Salida:
fuente
Si desea usar if, las siguientes declaraciones son otra solución:
fuente
fuente
Este código puede ser útil.
fuente
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.
fuente
Solución de una línea:
O:
fuente
Tal vez necesite una fórmula directa para el conjunto de bits de salida.
Vamos a mapear en bits:
'c':1 'd':0xb10 'e':0xb100 'f':0xb1000
Relación de isc (es 'c'):
Use las matemáticas si la fórmula 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))
[re]:
((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 cuadrados de ecuacionesor
es el producto de ecuacionesy tendrás una ecuación total de suma expresa y tienes una 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 elementos de cadena correspondería a la cadena lista.
array[sum]
te da la cuerda.fuente
Se puede hacer fácilmente como
fuente
La forma más nemotécnica de representar su pseudocódigo en Python sería:
fuente
if any(v >= 42 for v in (x, y, z)):
. Ej .). Y el rendimiento de los 3 métodos (2 in {x,y,z}
,2 in (x,y,z)
,any(_v == 2 for _v in (x,y,z))
) parece ser casi lo mismo en CPython3.6 (ver Gist )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}:
fuente
Parece que estás construyendo algún tipo de cifrado César.
Un enfoque mucho más generalizado es este:
salidas
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 desea, la línea final se puede cambiar a:
fuente
Puedes usar el diccionario:
fuente
Sin dict, prueba esta solución:
y da:
fuente
Esto te ayudara.
fuente
Puedes unir esto
en una variable
Cambia nuestras condiciones como:
Salida:
fuente
Problema
Mientras que el patrón para probar múltiples valores
es muy legible y funciona en muchas situaciones, hay una trampa:
Pero queremos tener
Solución
Una generalización de la expresión anterior se basa en la respuesta de ytpillai :
que se puede escribir como
Si bien esta expresión devuelve el resultado correcto, no es tan legible como la primera expresión :-(
fuente