Trong câu trả lời này, sẽ có hai phần: Hai giải pháp duy nhất và biểu đồ tốc độ cho các giải pháp cụ thể.
Xóa các mục trùng lặp
Hầu hết các câu trả lời này chỉ loại bỏ các mục trùng lặp có thể băm được , nhưng câu hỏi này không có nghĩa là nó không chỉ cần các mục có thể băm , nghĩa là tôi sẽ cung cấp một số giải pháp không yêu cầu các mục có thể băm .
bộ sưu tập. Bộ đếm là một công cụ mạnh mẽ trong thư viện tiêu chuẩn có thể hoàn hảo cho việc này. Chỉ có một giải pháp khác thậm chí có Counter trong đó. Tuy nhiên, giải pháp đó cũng bị giới hạn ở các khóa có thể băm .
Để cho phép các khóa không thể xóa trong Counter, tôi đã tạo một lớp Container, nó sẽ cố lấy hàm băm mặc định của đối tượng, nhưng nếu thất bại, nó sẽ thử chức năng nhận dạng của nó. Nó cũng định nghĩa một phương trình và phương thức băm . Điều này là đủ để cho phép các mặt hàng không thể phá vỡ trong giải pháp của chúng tôi. Các đối tượng không thể xóa sẽ được xử lý như thể chúng có thể băm được. Tuy nhiên, hàm băm này sử dụng danh tính cho các đối tượng không thể xóa được, nghĩa là hai đối tượng bằng nhau mà cả hai đều không thể thực hiện được. Tôi đề nghị bạn ghi đè lên điều này và thay đổi nó để sử dụng hàm băm của một loại có thể thay đổi tương đương (như sử dụng hash(tuple(my_list))
if my_list
là một danh sách).
Tôi cũng đã thực hiện hai giải pháp. Một giải pháp khác giữ thứ tự của các mục, sử dụng một lớp con của cả OrderedDict và Counter được đặt tên là 'OrderedCorer'. Bây giờ, đây là các chức năng:
from collections import OrderedDict, Counter
class Container:
def __init__(self, obj):
self.obj = obj
def __eq__(self, obj):
return self.obj == obj
def __hash__(self):
try:
return hash(self.obj)
except:
return id(self.obj)
class OrderedCounter(Counter, OrderedDict):
'Counter that remembers the order elements are first encountered'
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
def __reduce__(self):
return self.__class__, (OrderedDict(self),)
def remd(sequence):
cnt = Counter()
for x in sequence:
cnt[Container(x)] += 1
return [item.obj for item in cnt]
def oremd(sequence):
cnt = OrderedCounter()
for x in sequence:
cnt[Container(x)] += 1
return [item.obj for item in cnt]
remd là sắp xếp không theo thứ tự, oremd được sắp xếp theo thứ tự. Bạn có thể biết rõ cái nào nhanh hơn, nhưng tôi sẽ giải thích bằng mọi cách. Việc sắp xếp không theo thứ tự là hơi nhanh hơn. Nó giữ ít dữ liệu hơn, vì nó không cần thứ tự.
Bây giờ, tôi cũng muốn hiển thị các so sánh tốc độ của từng câu trả lời. Vì vậy, tôi sẽ làm điều đó ngay bây giờ.
Chức năng nào là nhanh nhất?
Để loại bỏ trùng lặp, tôi đã thu thập 10 hàm từ một vài câu trả lời. Tôi đã tính tốc độ của từng chức năng và đưa nó vào một biểu đồ bằng matplotlib.pyplot .
Tôi chia điều này thành ba vòng biểu đồ. Băm là bất kỳ đối tượng nào có thể được băm, không thể băm là bất kỳ đối tượng nào không thể băm. Trình tự được sắp xếp là một chuỗi bảo tồn trật tự, một chuỗi không có thứ tự không giữ trật tự. Bây giờ, đây là một vài điều khoản nữa:
Unableered Hashable là cho bất kỳ phương thức loại bỏ trùng lặp nào, mà không nhất thiết phải giữ trật tự. Nó không phải làm việc cho những thứ không thể, nhưng nó có thể.
Thứ tự Hashable là cho bất kỳ phương thức nào giữ thứ tự của các mục trong danh sách, nhưng nó không phải làm việc cho các mục không thể, nhưng nó có thể.
Thứ tự không thể xóa được là bất kỳ phương pháp nào giữ thứ tự của các mục trong danh sách và hoạt động cho các mục không thể xóa được.
Trên trục y là số giây cần thiết.
Trên trục x là số mà hàm được áp dụng.
Chúng tôi đã tạo các chuỗi cho các hàm băm không có thứ tự và các thứ tự băm được sắp xếp theo cách hiểu sau: [list(range(x)) + list(range(x)) for x in range(0, 1000, 10)]
Đối với không thể đặt hàng: [[list(range(y)) + list(range(y)) for y in range(x)] for x in range(0, 1000, 10)]
Lưu ý rằng có một 'bước' trong phạm vi vì nếu không có nó, điều này sẽ mất gấp 10 lần. Ngoài ra bởi vì theo quan điểm cá nhân của tôi, tôi nghĩ rằng nó có thể trông dễ đọc hơn một chút.
Cũng lưu ý các phím trên chú giải là những gì tôi đã cố đoán là phần quan trọng nhất của chức năng. Đối với chức năng nào làm tồi tệ nhất hoặc tốt nhất? Các biểu đồ nói cho chính nó.
Với việc giải quyết, đây là các biểu đồ.
Hashables không có thứ tự
(Phóng to lên)
Đặt hàng Hashables
(Phóng to lên)
Đặt mua Unhashables
(Phóng to lên)