Здається, що ОП стосувався лише випадку двох змінних, але оскільки StackOverflow також стосується тих, хто пізніше шукає те саме питання, я спробую тут детально розглянути загальний випадок; Одна попередня відповідь вже містить загальну відповідь із використанням itertools.permutations(), але цей метод призводить до O(N*N!)порівнянь, оскільки N!перестановки з Nелементами є кожен. (Це була основна мотивація цієї відповіді)
Спочатку давайте підсумуємо, як деякі методи у попередніх відповідях застосовуються до загального випадку, як мотивація методу, представленого тут. Я буду використовувати Aдля позначення (x, y)та Bдля позначення (a, b), які можуть бути кортежами довільної (але однакової) довжини.
set(A) == set(B)швидко, але працює лише в тому випадку, якщо значення є доступними, і ви можете гарантувати, що один з кортежів не містить жодних повторюваних значень. (Наприклад {1, 1, 2} == {1, 2, 2}, як вказував @ user2357112 під відповіддю @Daniel Mesejo)
Попередній метод може бути розширений для роботи з дублюючими значеннями, використовуючи словники з підрахунками, а не набори: (Це все ще має обмеження, що всі значення повинні бути доступними для перегляду, наприклад, змінні значення, як listне працюватимуть)
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)не вимагає змінних значень, але трохи повільніше, і вимагає замість цього впорядкованих значень. (Так, наприклад complex, не буде працювати)
A in itertools.permutations(B)не вимагає змінних або упорядкованих значень, але, як уже згадувалося, він має O(N*N!)складність, тому навіть із лише 11 предметами, це може зайняти більше секунди.
Отже, чи є спосіб бути настільки ж загальним, але робити це значно швидше? Чому так, "вручну" перевіряючи, чи є однакова кількість кожного елемента: (Складність цього полягає в O(N^2)тому, що це не добре і для великих входів; На моїй машині 10 к. Елементів можуть зайняти секунду - але з менші входи, як 10 елементів, це так само швидко, як і інші)
def unordered_eq(A, B):
for a in A:
if A.count(a) != B.count(a):
return False
return True
Щоб досягти найкращої продуктивності, можливо, dictспершу слід спробувати метод sorted-base, повернутися до countметоду -abased, якщо це не вдається через незмінні значення, і, нарешті, повернутися до методу-base, якщо це занадто не вдається через нерозбірливі значення.
x,y, a,b: це ints / floats / string, довільні об'єкти чи що? Якби вони були побудованів типах і можна було триматиx,yіa,bв упорядкованому порядку, тоді можна було б уникнути другої гілки. Зауважте, що створення набору спричинитьx,y, a,bхешування кожного з чотирьох елементів , який може бути, а може і не тривіальним, або матиме значення для продуктивності, що залежить повністю від типу об'єктів.