Comment tester plusieurs variables en fonction de la valeur?
Je suis en train de faire une fonction qui permettra de comparer plusieurs variables d'un entier et de sortie d'une chaîne de trois lettres. Je me demandais si il y avait un moyen de les traduire en Python. Donc, dire:
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")
qui permettrait le retour d'une liste de
["c", "d", "f"]
Est quelque chose comme cela possible?
- utilisation
1
en (n-uplet) - Lorsque vous souhaitez évaluer une liste de déclarations dans un tout manière, vous pouvez utiliser
any
/all
fonctions. Par exemple:all([1, 2, 3, 4, False])
retournera Falseall([True, 1, 2, 3])
retournera Trueany([False, 0, 0, False])
retournera Falseany([False, 0, True, False])
retournera True - J'ai fait un résumé de message basé sur les réponses ici: medium.com/codervlogger/...
- Cette question est très populaire en double objectif, mais je pense que c'est sous-optimale à cette fin. La plupart des gens essaient de faire quelque chose comme
if x == 0 or 1:
, ce qui est évidemment semblable àif x or y == 0:
, mais pourrait être un peu déroutant pour les débutants néanmoins. Etant donné le volume de "Pourquoi n'est pas monx == 0 or 1
de travail?" des questions, je préférerais utiliser les cette question comme nos canonique double cible de ces questions. - Prendre des précautions supplémentaires lors de la comparaison à "falsey" des valeurs comme
0
,0.0
ouFalse
. Vous pouvez facilement écrire du mauvais code qui donne la "bonne" réponse.
Vous devez vous connecter pour publier un commentaire.
Vous ne comprenez pas comment les expressions booléennes de travail; ils ne travaillent pas comme une phrase anglaise et suppose que vous parlez de la même comparaison pour tous les noms ici. Vous êtes à la recherche pour:
x
ety
sont par ailleurs évalués sur leur propre (False
si0
,True
contraire).Vous pouvez raccourcir à l'aide d'un test de confinement contre un n-uplet:
ou mieux encore:
à l'aide de un
set
de prendre avantage de la constante-coût de l'adhésion d'essai (in
prend un montant fixe de temps, quelle que soit la gauche opérande est).Lorsque vous utilisez
or
, python voit de chaque côté de l'opérateur séparé expressions. L'expressionx or y == 1
est traitée comme la première, un boolean test pourx
, alors si c'est Faux, l'expressiony == 1
est testé.Cela est dû à la priorité de l'opérateur. Le
or
opérateur a une priorité plus basse que la==
de test, de sorte que le dernier est évalué première.Cependant, même si cela était pas le cas, et l'expression
x or y or z == 1
a effectivement été interprété comme(x or y or z) == 1
au lieu de cela, ce serait encore de ne pas faire ce que vous vous attendez à faire.x or y or z
d'évaluer au premier argument qui est "truthy', par exemple, ne pasFalse
, numérique 0 ou vide (voir des expressions booléennes pour plus de détails sur ce que Python considère faux dans un contexte booléen).Donc pour les valeurs
x = 2; y = 1; z = 0
,x or y or z
permettrait de résoudre à2
, parce que c'est le premier vrai-comme valeur dans les arguments. Puis2 == 1
seraitFalse
, même siy == 1
seraitTrue
.Il en serait de même à l'inverse, de tester plusieurs valeurs par rapport à une seule variable;
x == 1 or 2 or 3
serait un échec pour les mêmes raisons. Utilisationx == 1 or x == 2 or x == 3
oux in {1, 2, 3}
.set
version. Tuple sont très bon marché à créer et à parcourir. Sur ma machine, au moins, les tuples sont plus rapides que les jeux, aussi longtemps que la taille de la n-uplet est autour de 4 à 8 éléments. Si vous devez analyser de plus, l'utilisation d'un ensemble, mais si vous êtes à la recherche d'un élément de 2-4 possibilités, un tuple est encore plus rapide! Si vous pouvez vous arranger pour la plupart des cas probable d'être le premier dans le tuple, la victoire est encore plus grand: (mon test:timeit.timeit('0 in {seq}'.format(seq=tuple(range(9, -1, -1))))
)set
littérale de notation pour ce test n'est pas une épargne à moins que le contenu de laset
littérale sont également littéraux, droit?if 1 in {x, y, z}:
ne peut pas mettre en cache lesset
, parce quex
,y
etz
pourrait changer, donc soit la solution a besoin pour construire unetuple
ouset
à partir de zéro, et je soupçonne que quelle que soit la recherche d'économies que vous pouvez obtenir lorsque la vérification de l'adhésion pourraient être submergés par une plus grandeset
moment de la création.in [...]
ouin {...}
) ne fonctionne que si le contenu de la liste ou un ensemble sont immuables littéraux de trop.'word1' in string and 'word2' in string...
). serait la même syntaxe (c'est à direstring in (word1, word2):
) les travaux dans ce scénario, ou, comme je suis dans l'attente, serait-il un échec?string
n'est pas contenue dans la séquence(word1, word2)
. Vous pouvez utiliserall(w in string for w in sequence_of_words_to_test)
si vous avez plusieurs mots de tester en une seule chaîne. Ou utiliser leword1 in string and word2 in string
approche si vous avez seulement 2 ou 3 chaînes de test, et ils sont codés en dur.in
n'est pas constante de temps "quelle que soit la gauche opérande est" - techniquement avecset
vous auriez besoin, au plus, le temps nécessaire pour retourner la valeur de hachage (le calculer si vous n'avez pas de cache) et font une est égale à vérifier, ce qui peut très bien prendre plus de temps constant. Bien que ce coût existe aussi avec des n-uplets.listobj[index]
que O(1) (fourniindex
n'est pas une coutume objet Python avec un mauvais__index__
mise en œuvre), ou le tri d'une liste *O(N log N) (à condition que le contenu n'ont pas de complexe de la commande implémentations jeter hors de comparaison des coûts). Pourcontains
opérations, le coût peut être supposée constante. Si le hachage coût pour un "mauvais acteur" de l'objet est grande, ça va encore être le même coût indépendant de la taille de l'ensemble que vous tester.set
approche n'est pas évidente, et il y a toujours le générique piège avec "falsey" non-valeurs entières:False in (1,0,2)
et0.0 in (1,0,2)
à la fois donnerTrue
. b) Alias: l'utilisation accidentelle de laif x is y
avec de petits nombres entiers et l'internement des chaînes de caractères peut aussi donner la mauvaise réponse. Sont de cette question et ses réponses uniquement pour les entiers? c)in
est surchargé pour les chaînes et les séquences; considérer:'77' in '777'
est Vrai, mais'77' in ('666','777')
est Faux. d) ...dict() == collections.Counter()
est Vrai. e) les Itérateurs et les plages:[0,1,2] == range(3)
est Faux. Bien que[0,1,2] == list(range(3))
est VraiFalse == 0
est également Vrai, et donc est0.0 == 0
. Et au moins avec un ensemble d'adhésion d'essai vous éviter parfois faitis
erreur. Je ne dis rien sur l'utilisation dein
sur des chaînes ou des n-uplets.Votre problème est plus facile à régler avec un dictionnaire de la structure comme:
d = "cdef"
qui conduit àMyList = ["cdef"[k] for k in [x, y, z]]
map(lambda i: 'cdef'[i], [x, y, z])
[x, y, z]
Comme indiqué par Martijn Pieters, le bon, et le plus rapide, le format est:
À l'aide de ses conseils ont séparé si-états, de sorte que Python va lire chaque énoncé de savoir si les anciens ont été
True
ouFalse
. Tels que:Cela va fonctionner, mais si vous êtes à l'aise à l'aide de dictionnaires (voir ce que j'ai fait là), vous pouvez nettoyer ce en faisant un premier dictionnaire de la cartographie du nombre de lettres que vous voulez, puis juste à l'aide d'une boucle for:
La voie la plus directe pour écrire
x or y or z == 0
estMais je ne crois pas, vous l'aimez. 🙂
Et de cette façon, c'est moche.
L'autre sens (une meilleure) est:
BTW beaucoup de
if
s) peut être écrit quelque chose comme celadict
au lieu d'une clé, vous obtiendrez des erreurs parce que la valeur de retour de.append
estNone
, et en appelantNone
donne unAttributeError
. En général je suis d'accord avec cette méthode, bien que.Si vous ÊTES très très paresseux, vous pouvez mettre les valeurs dans un tableau. Comme
Vous pouvez aussi mettre les chiffres et de lettres dans un dictionnaire et de le faire, mais ce n'est probablement BEAUCOUP plus compliqué que de simplement les instructions if. C'est ce que vous obtenez pour essayer d'être très paresseux 🙂
Une chose de plus, votre
de compiler, mais pas dans la façon dont vous le souhaitez. Lorsqu'il vous suffit de mettre une variable dans une instruction if (exemple)
le programme va vérifier si la variable n'est pas nulle. Une autre façon d'écrire la déclaration ci-dessus (ce qui fait plus de sens) est
Bool est une fonction intégrée de fonction en python qui fait de la commande de vérification d'une proposition booléenne (Si vous ne savez pas ce que c'est, c'est ce que vous essayez de vous rendre dans votre déclaration si en ce moment :))
Une autre manière paresseuse que j'ai trouvé est :
Pour vérifier si une valeur est contenue dans un ensemble de variables, vous pouvez utiliser la fonction intégrée de modules
itertools
etoperator
.Par exemple:
Importations:
Déclarer des variables:
Créer le mappage des valeurs (dans l'ordre que vous voulez vérifier):
Utilisation
itertools
pour permettre la répétition des variables:Enfin, l'utilisation de la
map
fonction pour créer un itérateur:Puis, lors de la vérification des valeurs (dans l'ordre d'origine), l'utilisation
next()
:etc...
Ce qui a un avantage sur le
lambda x: x in (variables)
parce queoperator
est une fonction intégrée de module et il est plus rapide et plus efficace que l'utilisationlambda
qui a créer un personnalisé en place de la fonction.Une autre option pour vérifier si il est non nulle (ou Faux) de la valeur dans une liste:
Équivalent:
Je pense que ce sera mieux le gérer:
De sortie:
Est la bonne approche, car il commande les variables, ce qui semble être votre but ici.
{z,y,x}
est{0,1,3}
quel que soit l'ordre des paramètres.De cette façon, l'ensemble de la solution est O(n).
Si vous souhaitez utiliser si, d'autre des déclarations suivantes est une autre solution:
Toutes les excellentes réponses fournies ici de se concentrer sur les besoins spécifiques de l'original de l'affiche et de se concentrer sur la
if 1 in {x,y,z}
solutions mises de l'avant par Martijn Pieters.Ce qu'ils ignorent, c'est le plus large implication de la question:
Comment puis-je tester une variable à l'encontre de plusieurs valeurs?
La solution proposée ne fonctionne pas pour les partiels succès si l'aide de cordes par exemple:
Test si la chaîne de caractères "Sauvage" est à valeurs multiples
ou
pour ce scénario, il est plus facile de convertir une chaîne de caractères
Il convient de noter, cependant, comme mentionné par
@codeforester
, ce mot boundries sont perdus avec cette méthode, comme dans:les 3 lettres
rot
n'existe pas en combinaison dans la liste, mais pas comme un mot. Test pour "pourrir" serait un échec, mais si l'un des éléments de la liste ont été "pourrir en enfer", qui serait défaillant.Le résultat étant, faites attention à vos critères de recherche si l'utilisation de cette méthode et de savoir qu'elle ne cette limitation.
Ce code peut être utile
Une solution en ligne:
Ou:
Vous pouvez essayer la méthode indiquée ci-dessous. Dans cette méthode, vous aurez la liberté de préciser d'entrée/le nombre de variables que vous souhaitez entrer.
Peut-être vous avez besoin de formule directe pour la sortie bits.
Nous allons carte de bits:
'c':1 'd':0xb10 'e':0xb100 'f':0xb1000
Rapport de l'isc (est 'c'):
Utiliser les maths si la formule 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))
...
La connexion de ces formules en logique suivante:
and
est la somme des carrés des équationsor
est le produit des équationset vous aurez un total équation
express somme et vous avez la formule de la somme
puis sum&1 est c, sum&2 d, sum&4 est e, sum&5 est f
Après cela, vous pouvez formulaire prédéfini tableau où l'indice de la chaîne éléments correspondent à des prêts de la chaîne.
array[sum]
vous donne la chaîne.Il peut être fait facilement que
Les plus mnémonique façon de représenter votre pseudo-code en Python serait:
if any(v >= 42 for v in (x, y, z)):
). Et la performance de tous les 3 méthodes (2 in {x,y,z}
,2 in (x,y,z)
,any(_v == 2 for _v in (x,y,z))
) semble être presque la même dans CPython3.6 (voir Résumé)Dirait que vous êtes en train de construire une sorte de César de chiffrement.
Beaucoup plus généralisée de l'approche est ceci:
sorties
Ne sais pas si c'est un côté souhaité effet de votre code, mais l'ordre de votre sortie sera toujours triés.
Si c'est ce que vous voulez, la dernière ligne peut être changé:
De tester plusieurs variables avec une valeur unique:
if 1 in {a,b,c}:
De tester plusieurs valeurs à une variable:
if a in {1, 2, 3}:
Vous pouvez utiliser le dictionnaire :
Cela va vous aider.