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 à des O(N*N!)
comparaisons, car il existe des N!
permutations avec des N
é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)
et B
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)
def counts(items):
d = {}
for item in items:
d[item] = d.get(item, 0) + 1
return d
counts(A) == counts(B)
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 exemple complex
, 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 la O(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)
def unordered_eq(A, B):
for a in A:
if A.count(a) != B.count(a):
return False
return True
Pour obtenir les meilleures performances, on peut vouloir essayer d'abord la dict
méthode basée sur, se replier sur la sorted
méthode basée sur si cela échoue en raison de valeurs incontrôlables, et enfin retomber sur la count
méthode basée sur si cela échoue aussi en raison de valeurs non ordonnancables.
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.