Có vẻ như OP chỉ quan tâm đến trường hợp của hai biến, nhưng vì StackOverflow cũng dành cho những người tìm kiếm cùng một câu hỏi sau đó, tôi sẽ cố gắng giải quyết trường hợp chung ở đây một cách chi tiết; Một câu trả lời trước đã có câu trả lời chung chung bằng cách sử dụng itertools.permutations()
, nhưng phương pháp đó dẫn đến O(N*N!)
so sánh, vì có N!
hoán vị vớiN
các mục. (Đây là động lực chính cho câu trả lời này)
Trước tiên, hãy tóm tắt làm thế nào một số phương pháp trong các câu trả lời trước áp dụng cho trường hợp chung, như là động lực cho phương pháp được trình bày ở đây. Tôi sẽ sử dụng A
để tham khảo (x, y)
và B
tham khảo(a, b)
, có thể là các bộ dữ liệu có độ dài tùy ý (nhưng bằng nhau).
set(A) == set(B)
là nhanh, nhưng chỉ hoạt động nếu các giá trị có thể băm và bạn có thể đảm bảo rằng một trong các bộ dữ liệu không chứa bất kỳ giá trị trùng lặp nào. (Ví dụ.{1, 1, 2} == {1, 2, 2}
như được chỉ ra bởi @ user2357112 dưới câu trả lời của @Daniel Mesejo)
Phương thức trước có thể được mở rộng để hoạt động với các giá trị trùng lặp bằng cách sử dụng từ điển với số đếm, thay vì bộ: (Điều này vẫn có giới hạn là tất cả các giá trị cần phải được băm, ví dụ: các giá trị có thể thay đổi như list
sẽ không hoạt động)
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)
không yêu cầu giá trị có thể băm, nhưng chậm hơn một chút và thay vào đó yêu cầu giá trị có thể sắp xếp. (Vì vậy, ví dụ như complex
sẽ không làm việc)
A in itertools.permutations(B)
không yêu cầu các giá trị có thể băm hoặc có thể sắp xếp, nhưng như đã đề cập, nó có O(N*N!)
độ phức tạp, vì vậy ngay cả chỉ với 11 mục, nó có thể mất hơn một giây để hoàn thành.
Vì vậy, có cách nào để chung chung, nhưng làm nó nhanh hơn đáng kể? Tại sao có, bằng cách "kiểm tra" thủ công rằng có cùng số lượng của từng mặt hàng: (Độ phức tạp của mặt hàng này là O(N^2)
, vì vậy điều này cũng không tốt cho đầu vào lớn; Trên máy của tôi, 10k mặt hàng có thể chiếm một giây - nhưng với đầu vào nhỏ hơn, như 10 mục, điều này cũng nhanh như các mục khác)
def unordered_eq(A, B):
for a in A:
if A.count(a) != B.count(a):
return False
return True
Để có được hiệu suất tốt nhất, trước tiên, người ta có thể muốn thử dict
phương thức dựa trên cơ sở, quay lại sorted
phương thức dựa trên cơ sở nếu điều đó không thành công do các giá trị không thể thực hiện được và cuối cùng quay lại count
phương thức dựa trên cơ sở nếu quá thất bại do các giá trị không thể sắp xếp được.
x,y, a,b
là: chúng là ints / float / chuỗi, các đối tượng tùy ý, hoặc những gì? Nếu chúng là các kiểu dựng sẵn và có thể giữ cả haix,y
vàa,b
theo thứ tự được sắp xếp, thì bạn có thể tránh được nhánh thứ hai. Lưu ý rằng việc tạo một tập hợp sẽ khiến mỗi một trong bốn phần tửx,y, a,b
được băm, có thể hoặc không tầm thường hoặc có hàm ý hiệu suất tùy thuộc hoàn toàn vào loại đối tượng chúng.