J'essaie d'évaluer ((x == a and y == b) or (x == b and y == a))
en Python, mais cela semble un peu bavard. Existe-t-il une manière plus élégante?
python
boolean-logic
LetEpsilonBeLessThanZero
la source
la source
x,y, a,b
: s'agit-il d'entiers / flottants / chaînes, d'objets arbitraires ou quoi? S'il s'agissait de types intégrés et qu'il était possible de les conserver tous les deuxx,y
eta,b
dans l'ordre trié, vous pourriez éviter la deuxième branche. Notez que la création d'un ensemble entraînera le hachage de chacun des quatre élémentsx,y, a,b
, ce qui pourrait être trivial ou non ou avoir une implication de performance dépendant entièrement du type d'objets qu'ils sont.((x == a and y == b) or (x == b and y == a))
peut sembler yukky, mais 1) son intention est limpide et intelligible pour tous les programmeurs non-Python, pas cryptique 2) les interprètes / compilateurs le géreront toujours bien et il ne peut en aucun cas résulter en un code non performant, contrairement au alternatives. Ainsi, «plus élégant» peut aussi avoir de sérieux inconvénients.Réponses:
Si les éléments sont hachables, vous pouvez utiliser des ensembles:
la source
{1, 1, 2} == {1, 2, 2}
. À ce stade, vous avez besoin desorted
ouCounter
.Je pense que le mieux que vous puissiez obtenir est de les regrouper en tuples:
Ou, peut-être envelopper cela dans une recherche d'ensemble
Tout comme cela a été mentionné par quelques commentaires, j'ai fait quelques synchronisations, et les tuples et les ensembles semblent fonctionner de manière identique ici lorsque la recherche échoue:
Bien que les tuples soient en fait plus rapides lorsque la recherche réussit:
J'ai choisi d'utiliser un ensemble parce que je fais une recherche d'adhésion, et conceptuellement, un ensemble est mieux adapté à ce cas d'utilisation qu'un tuple. Si vous avez mesuré une différence significative entre les deux structures dans un cas d'utilisation particulier, optez pour la plus rapide. Je ne pense pas que la performance soit un facteur ici.
la source
if (a, b) in ((x, y), (y, x))
Mais tu pourrais le faire ?set
solution dans la réponse à la solution de tuple de @Brilliand?Les tuples le rendent légèrement plus lisible:
Cela donne un indice: nous vérifions si la séquence
x, y
est égale à la séquencea, b
mais ignorons l'ordre. C'est juste définir l'égalité!la source
,
crée un tuple, pas une liste. donc(x, y)
et(a, b)
sont des tuples, les mêmes quex, y
eta, b
.list
type Python . Modifié car en effet c'était déroutant.Si les articles ne sont pas hachables, mais prennent en charge les comparaisons de commande, vous pouvez essayer:
la source
complex
par exemple.La façon la plus élégante, à mon avis, serait
C'est une meilleure façon que d'utiliser des ensembles, c'est-à-dire
{a, b} == {y, x}
, comme indiqué dans d'autres réponses, car nous n'avons pas besoin de penser si les variables sont hachables.la source
S'il s'agit de chiffres, vous pouvez les utiliser
(x+y)==(a+b) and (x*y)==(a*b)
.S'il s'agit d'articles comparables, vous pouvez les utiliser
min(x,y)==min(a,b) and max(x,y)==max(a,b)
.Mais
((x == a and y == b) or (x == b and y == a))
est clair, sûr et plus général.la source
Comme généralisation à plus de deux variables, nous pouvons utiliser
itertools.permutations
. C'est au lieu denous pouvons écrire
Et bien sûr la version à deux variables:
la source
O(N*N!)
; Pour 11 variables, cela peut prendre plus d'une seconde pour terminer. (J'ai posté une méthode plus rapide, mais elle prend toujoursO(N^2)
et commence à prendre plus d'une seconde sur les variables 10k; Il semble donc que cela puisse être fait rapidement ou généralement (par rapport à l'habilité / ordre), mais pas les deux: P)Vous pouvez utiliser des tuples pour représenter vos données, puis vérifier l'inclusion de l'ensemble, comme:
la source
Vous avez déjà la solution la plus lisible . Il existe d'autres façons d'exprimer cela, peut-être avec moins de caractères, mais elles sont moins simples à lire.
Selon ce que les valeurs représentent réellement, votre meilleur pari est d' encapsuler le chèque dans une fonction avec un nom parlant . Alternativement ou en plus, vous pouvez modéliser les objets x, y et a, b chacun dans des objets de classe supérieure dédiés que vous pouvez ensuite comparer avec la logique de la comparaison dans une méthode de contrôle d'égalité de classe ou une fonction personnalisée dédiée.
la source
Il semble que l'OP ne concernait que le cas de deux variables, mais comme StackOverflow s'adresse également à ceux qui recherchent la même question plus tard, je vais essayer d'aborder le cas générique ici en détail; Une réponse précédente contient déjà une réponse générique utilisant
itertools.permutations()
, mais cette méthode conduit à desO(N*N!)
comparaisons, car il existe desN!
permutations avec desN
éléments chacun. (Ce fut la principale motivation de cette réponse)Tout d'abord, résumons comment certaines des méthodes des réponses précédentes s'appliquent au cas générique, comme motivation pour la méthode présentée ici. Je vais utiliser
A
pour faire référence à(x, y)
etB
pour faire référence à(a, b)
, qui peuvent être des tuples de longueur arbitraire (mais égale).set(A) == set(B)
est rapide, mais ne fonctionne que si les valeurs sont hachables et vous pouvez garantir que l'un des tuples ne contient aucune valeur en double. (Par exemple{1, 1, 2} == {1, 2, 2}
, comme l'a souligné @ user2357112 dans la réponse de @Daniel Mesejo)La méthode précédente peut être étendue pour fonctionner avec des valeurs en double en utilisant des dictionnaires avec des nombres, au lieu d'ensembles: (Cela a toujours la limitation que toutes les valeurs doivent être lavables, donc par exemple. Les valeurs mutables comme
list
ne fonctionneront pas)sorted(A) == sorted(B)
ne nécessite pas de valeurs lavables, mais est légèrement plus lent et requiert des valeurs ordonnables à la place. (Donc, par exemplecomplex
, ne fonctionnera pas)A in itertools.permutations(B)
ne nécessite pas de valeurs lavables ou ordonnables, mais comme déjà mentionné, il a de laO(N*N!)
complexité, donc même avec seulement 11 articles, il peut prendre plus d'une seconde pour terminer.Alors, y a-t-il un moyen d'être aussi général, mais le faire beaucoup plus rapidement? Pourquoi oui, en vérifiant "manuellement" qu'il y a la même quantité de chaque élément: (La complexité de celui-ci est
O(N^2)
, donc ce n'est pas bon non plus pour les entrées de grande taille; Sur ma machine, les éléments 10k peuvent prendre plus d'une seconde - mais avec entrées plus petites, comme 10 articles, c'est aussi rapide que les autres)Pour obtenir les meilleures performances, on peut vouloir essayer d'abord la
dict
méthode basée sur, se replier sur lasorted
méthode basée sur si cela échoue en raison de valeurs incontrôlables, et enfin retomber sur lacount
méthode basée sur si cela échoue aussi en raison de valeurs non ordonnancables.la source