J'essaie de créer une fonction qui comparera plusieurs variables à un entier et produira une chaîne de trois lettres. Je me demandais s'il y avait un moyen de traduire cela en Python. Dites donc:
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 retournerait une liste de:
["c", "d", "f"]
Est-ce que quelque chose comme ça est possible?
python
if-statement
comparison
match
boolean-logic
user1877442
la source
la source
1
dans (tuple)any
/all
. Par exemple:all([1, 2, 3, 4, False])
retournera Falseall([True, 1, 2, 3])
retournera Trueany([False, 0, 0, False])
reviendra Falseany([False, 0, True, False])
retournera Trueif x == 0 or 1:
, qui est bien sûr similaire àif x or y == 0:
, mais qui pourrait néanmoins être un peu déroutant pour les débutants. Étant donné le volume de "Pourquoi nex == 0 or 1
travaille- t-il pas ?" questions, je préfère de loin utiliser cette question comme notre cible canonique en double pour ces questions.0
,0.0
ouFalse
. Vous pouvez facilement écrire un code incorrect qui donne la «bonne» réponse.Réponses:
Vous comprenez mal le fonctionnement des expressions booléennes; ils ne fonctionnent pas comme une phrase en anglais et devinez que vous parlez de la même comparaison pour tous les noms ici. Tu recherches:
x
ety
sont par ailleurs évalués par eux-mêmes (False
si0
,True
sinon).Vous pouvez raccourcir cela en utilisant un test de confinement par rapport à un tuple :
ou mieux encore:
en utilisant a
set
pour bénéficier du test d'appartenance à coût constant (in
prend un temps fixe quel que soit l'opérande de gauche).Lorsque vous utilisez
or
, python voit chaque côté de l'opérateur comme des expressions distinctes . L'expressionx or y == 1
est d'abord traitée comme un test booléenx
, puis si c'est faux, l'expressiony == 1
est testée.Cela est dû à la priorité de l'opérateur . L'
or
opérateur a une priorité plus faible que le==
test, ce dernier est donc évalué en premier .Cependant, même si ce n'était pas le cas et que l'expression
x or y or z == 1
était en fait interprétée comme telle(x or y or z) == 1
, cela ne ferait toujours pas ce que vous attendez d'elle.x or y or z
évaluerait le premier argument qui est «véridique», par exemple nonFalse
, numérique 0 ou vide (voir les 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
se résoudrait en2
, car c'est la première valeur vraie dans les arguments. Ce2 == 1
serait le casFalse
, même s'il ley == 1
seraitTrue
.La même chose s'appliquerait à l'inverse; tester plusieurs valeurs par rapport à une seule variable;
x == 1 or 2 or 3
échouerait pour les mêmes raisons. Utilisezx == 1 or x == 2 or x == 3
oux in {1, 2, 3}
.la source
set
version. Les tuples sont très bon marché à créer et à parcourir. Sur ma machine au moins, les tuples sont plus rapides que les ensembles tant que la taille du tuple est d'environ 4 à 8 éléments. Si vous devez numériser plus que cela, utilisez un ensemble, mais si vous recherchez un élément sur 2 à 4 possibilités, un tuple est encore plus rapide! Si vous pouvez prendre des dispositions pour le cas le plus susceptible 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
notation littérale pour ce test n'est pas une économie à moins que le contenu duset
littéral ne soit également littéral, non?if 1 in {x, y, z}:
ne peut pas mettre en cache laset
, parce quex
,y
etz
pourrait changer, de sorte que soit les besoins en solution pour construire untuple
ou àset
partir de zéro, et je soupçonne ce que lookup économies que vous pourriez obtenir lors de la vérification d'adhésion seraient submergés par une plus grandeset
date de création.in [...]
ouin {...}
) ne fonctionne que si le contenu de la liste ou de l'ensemble est également des littéraux immuables.Votre problème est plus facilement résolu avec une structure de dictionnaire comme:
la source
d = "cdef"
ce qui mène àMyList = ["cdef"[k] for k in [x, y, z]]
map(lambda i: 'cdef'[i], [x, y, z])
[x, y, z]
Comme l'a déclaré Martijn Pieters, le format correct et le plus rapide est:
En utilisant son conseil, vous auriez maintenant des instructions if séparées afin que Python lise chaque instruction, que les premières soient
True
ouFalse
. Tel que:Cela fonctionnera, mais si vous êtes à l'aise avec les dictionnaires (voir ce que j'ai fait là-bas), vous pouvez nettoyer cela en créant un dictionnaire initial mappant les nombres aux lettres que vous voulez, puis en utilisant simplement une boucle for:
la source
La façon directe d'écrire
x or y or z == 0
estMais je ne pense pas, vous l'aimez. :) Et cette façon est moche.
L'autre façon (une meilleure) est:
BTW beaucoup de
if
s pourraient être écrits comme quelque chose comme çala source
dict
lieu d'une clé, vous obtiendrez des erreurs car la valeur de retour de.append
estNone
, et l'appelNone
donne unAttributeError
. En général, je suis d'accord avec cette méthode.filter
serait mieux que celamap
, car il ne retournera que les cas où lambda est évalué comme vraiany(v == 0 for v in (x, y, z))
Si vous êtes très très paresseux, vous pouvez mettre les valeurs dans un tableau. Tel que
Vous pouvez également mettre les chiffres et les lettres dans un dictionnaire et le faire, mais c'est probablement beaucoup plus compliqué que les simples instructions if. C'est ce que vous obtenez en essayant d'être très paresseux :)
Encore une chose, votre
va compiler, mais pas de la façon dont vous le souhaitez. Lorsque vous mettez simplement une variable dans une instruction if (exemple)
le programme vérifiera si la variable n'est pas nulle. Une autre façon d'écrire la déclaration ci-dessus (qui a plus de sens) est
Bool est une fonction intégrée en python qui effectue essentiellement la commande de vérification d'une instruction booléenne (si vous ne savez pas ce que c'est, c'est ce que vous essayez de faire dans votre instruction if en ce moment :))
Une autre façon paresseuse que j'ai trouvée est:
la source
list
est un module intégré Python; utilisez un autre nom à la place, commexyz
par exemple. Pourquoi construisez-vous la liste en quatre étapes alors que vous pouvez en faire une, c'estxyz = [x, y, z]
-à- dire ? N'utilisez pas de listes parallèles, utilisez plutôt un dict. Dans l'ensemble, cette solution est beaucoup plus compliquée que celle de ThatGuyRussell . Aussi pour la dernière partie, pourquoi ne pas faire de compréhension, c'est à direany(v == 0 for v in (x, y, z))
? Les tableaux sont également quelque chose d'autre en Python.Pour vérifier si une valeur est contenue dans un ensemble de variables, vous pouvez utiliser les modules intégrés
itertools
etoperator
.Par exemple:
Importations:
Déclarez les variables:
Créez un mappage de valeurs (dans l'ordre que vous souhaitez vérifier):
Utilisez
itertools
pour permettre la répétition des variables:Enfin, utilisez la
map
fonction pour créer un itérateur:Ensuite, lors de la vérification des valeurs (dans l'ordre d'origine), utilisez
next()
:etc...
Cela a un avantage sur le
lambda x: x in (variables)
caroperator
est un module intégré et est plus rapide et plus efficace que l'utilisationlambda
qui doit créer une fonction sur place personnalisée.Une autre option pour vérifier s'il y a une valeur non nulle (ou fausse) dans une liste:
Équivalent:
la source
Définir est la bonne approche ici, car il ordonne les variables, ce qui semble être votre objectif ici.
{z,y,x}
est{0,1,3}
quel que soit l'ordre des paramètres.De cette façon, toute la solution est O (n).
la source
Toutes les excellentes réponses fournies ici se concentrent sur l'exigence spécifique de l'affiche originale et se concentrent sur la
if 1 in {x,y,z}
solution proposée par Martijn Pieters.Ce qu'ils ignorent, c'est l'implication plus large de la question:
comment tester une variable par rapport à plusieurs valeurs?
La solution fournie ne fonctionnera pas pour les hits partiels si vous utilisez des chaînes par exemple:
Testez si la chaîne "Wild" est dans plusieurs valeurs
ou
pour ce scénario, il est plus facile de convertir en chaîne
Il convient de noter cependant, comme mentionné par
@codeforester
, que les limites de mots sont perdues avec cette méthode, comme dans:les 3 lettres
rot
existent en combinaison dans la liste mais pas en tant que mot individuel. Le test de «pourriture» échouerait, mais si l'un des éléments de la liste était «pourriture en enfer», cela échouerait également.Le résultat étant, soyez prudent avec vos critères de recherche si vous utilisez cette méthode et sachez qu'elle a cette limitation.
la source
Je pense que cela va mieux gérer:
Production:
la source
Si vous souhaitez utiliser les instructions if, else, voici une autre solution:
la source
la source
Ce code peut être utile
la source
Vous pouvez essayer la méthode indiquée ci-dessous. Dans cette méthode, vous aurez la liberté de spécifier / saisir le nombre de variables que vous souhaitez saisir.
la source
Solution en une ligne:
Ou:
la source
Vous avez peut-être besoin d'une formule directe pour le jeu de bits de sortie.
Mappons sur des bits:
'c':1 'd':0xb10 'e':0xb100 'f':0xb1000
Relation de isc (est «c»):
Utilisez les mathématiques 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))
[ré]:
((x-1)(y-1)(z-1)=0 and isc=2) or (((xyz=0 and isd=2) or (isc=0)) and (isc=0))
...
Connectez ces formules en suivant la logique:
and
est la somme des carrés des équationsor
est le produit d'équationset vous aurez une somme expresse d'équation totale et vous avez une formule totale de somme
alors somme & 1 est c, somme & 2 est d, somme & 4 est e, somme & 5 est f
Après cela, vous pouvez former un tableau prédéfini où l'index des éléments de chaîne correspondrait à la chaîne prête.
array[sum]
vous donne la chaîne.la source
Cela peut être fait facilement
la source
La façon la plus mnémonique de représenter votre pseudo-code en Python serait:
la source
if any(v >= 42 for v in (x, y, z)):
). Et les performances des 3 méthodes (2 in {x,y,z}
,2 in (x,y,z)
,any(_v == 2 for _v in (x,y,z))
) semble être à peu près la même chose dans CPython3.6 (voir Gist )Pour tester plusieurs variables avec une seule valeur:
if 1 in {a,b,c}:
Pour tester plusieurs valeurs avec une variable:
if a in {1, 2, 3}:
la source
On dirait que vous construisez une sorte de chiffre César.
Une approche beaucoup plus généralisée est la suivante:
les sorties
Je ne sais pas si c'est un effet secondaire souhaité de votre code, mais l'ordre de votre sortie sera toujours trié.
Si c'est ce que vous voulez, la dernière ligne peut être remplacée par:
la source
Vous pouvez utiliser le dictionnaire:
la source
Sans dict, essayez cette solution:
et donne:
la source
Cela vous aidera.
la source
Vous pouvez unir cela
dans une variable.
Modifiez nos conditions comme:
Production:
la source
Problème
Alors que le modèle pour tester plusieurs valeurs
est très lisible et fonctionne dans de nombreuses situations, il y a un écueil:
Mais nous voulons avoir
Solution
Une généralisation de l'expression précédente est basée sur la réponse d' ytpillai :
qui peut s'écrire
Bien que cette expression renvoie le bon résultat, elle n'est pas aussi lisible que la première expression :-(
la source