Здається, що ОП стосувався лише випадку двох змінних, але оскільки 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
хешування кожного з чотирьох елементів , який може бути, а може і не тривіальним, або матиме значення для продуктивності, що залежить повністю від типу об'єктів.