Tại sao không có các vùng chứa được sắp xếp trong các thư viện chuẩn của Python?


81

Có quyết định thiết kế Python (PEP) ngăn không cho một vùng chứa đã sắp xếp được thêm vào Python không?

( OrderedDictkhông phải là một vùng chứa được sắp xếp vì nó được sắp xếp theo thứ tự chèn.)


1
thích các bộ sưu tập.OrderedDict?
utdemir

1
Nó chỉ nhanh hơn. O (1) cho hashmap so với O (log n) cho tập hợp có thứ tự.
vartec

18
@utdmr: OrderedDict được sắp xếp theo thứ tự chèn - không phải theo khóa tùy ý, giống như một vùng chứa được sắp xếp.
Neil G

1
@ Hi-Angel Không, đó không phải là ý nghĩa của vùng chứa được sắp xếp . Ví dụ:
Neil G

1
"vùng chứa được sắp xếp là vùng chứa sắp xếp các phần tử khi chèn". Không chính xác: Tôi muốn nói rằng một vùng chứa được sắp xếp là một vùng chứa có giao diện được sắp xếp hiệu quả (theo một khóa tùy ý) lặp đi lặp lại và tìm kiếm. Sự hiểu lầm của bạn bắt nguồn từ định nghĩa khác thường của bạn.
Neil G,

Câu trả lời:


76

Đó là một quyết định thiết kế có ý thức từ phía Guido (anh ấy thậm chí hơi miễn cưỡng về việc bổ sung collectionsmô-đun). Mục tiêu của ông là duy trì "một cách rõ ràng để làm điều đó" khi nói đến việc lựa chọn kiểu dữ liệu cho các ứng dụng.

Khái niệm cơ bản là nếu người dùng đủ tinh tế để nhận ra rằng các loại nội trang không phải là giải pháp phù hợp cho vấn đề của họ, thì họ cũng có nhiệm vụ tìm một thư viện bên thứ ba thích hợp.

Do danh sách + sắp xếp, danh sách + heapq và list + bisect bao gồm nhiều trường hợp sử dụng mà nếu không sẽ dựa vào cấu trúc dữ liệu đã được sắp xếp vốn có và các gói như Blist tồn tại, không có ổ đĩa lớn để thêm phức tạp hơn trong không gian này để thư viện tiêu chuẩn.

Theo một số cách, nó tương tự như thực tế là không có mảng đa chiều trong thư viện tiêu chuẩn, thay vào đó hãy nhường nhiệm vụ đó cho NumPy folks.


2
Cảm ơn, tôi đang tìm kiếm động lực đằng sau quyết định thiết kế này. Đây chính xác là loại câu trả lời mà tôi đang tìm kiếm. Bản năng ban đầu của tôi sẽ không làm mọi việc theo cách này, nhưng lập luận rất thuyết phục.
Neil G

collections.Countercó thể được sử dụng như tập hợp được sắp xếp. Mặc dù nó có thể không hiệu quả.
coderek

1
@coderek: collections.Counterkhông được sắp xếp và không thích hợp để đại diện cho một tập hợp được sắp xếp.
user2357112 hỗ trợ Monica

Nhưng ít nhất không nên được sắp xếp từ điển tích hợp sẵn? Từ điển phải được lưu trữ được sắp xếp để cung cấp khả năng truy cập nhanh vào các phần tử, điều này có vẻ kỳ lạ đối với tôi là khi bạn lặp lại nó, bằng cách nào đó bạn vẫn có các mục không được sắp xếp.
Hi-Angel,

1
@ Hi-Angel dictlà một bảng băm.
Neil G

80

Ngoài ra còn có một con trăn sortedcontainers mô-đun mà dụng cụ được sắp xếp danh sách, dict, và các loại thiết lập. Nó rất giống với Blist nhưng được triển khai bằng Python thuần túy và trong hầu hết các trường hợp nhanh hơn .

>>> from sortedcontainers import SortedSet
>>> ss = SortedSet([3, 7, 2, 2])
>>> ss
SortedSet([2, 3, 7])

Nó cũng có chức năng không phổ biến đối với các gói khác:

>>> from sortedcontainers import SortedDict
>>> sd = SortedDict((num, num) for num in range(100000))
>>> sd.iloc[-5] # Lookup the fifth-to-last key.
99995

Tuyên bố từ chối trách nhiệm: Tôi là tác giả của mô-đun điều khiển được sắp xếp.


1
Đẹp! Bạn có thể muốn xem xét cập nhật tài liệu của mình để xác định rằng bộ nhớ cơ bản là một sợi dây .
Neil G

1
@NeilG Cảm ơn! Một vài lưu ý: Blist không được viết bằng Python thuần túy. Các loại tập hợp, danh sách và dict được sắp xếp dựa trên loại Blist là B + -tree được triển khai trong C. Ngoài ra, cấu trúc cơ bản không thực sự là một sợi dây; nó giống với B + -tree hơn nhưng chỉ có một mức nút.
GrantJ

3
Nó thực sự là một ví dụ tuyệt vời về việc big-O có thể gây hiểu lầm. Nó có thể sẽ làm chậm khoảng một nghìn tỷ phần tử nhưng hầu hết mọi người không có một terabyte bộ nhớ để lo lắng về điều đó. Tôi đã thử nghiệm nó với hàng tỷ phần tử và nó nhanh như triển khai C. Nó cũng sử dụng ít bộ nhớ hơn nhiều bằng cách duy trì một cấu trúc dựa trên danh sách đơn giản như vậy.
GrantJ

1
Yeah tuyệt đối. Đó là đối số tương tự mà họ sử dụng để biện minh cho việc sử dụng loại cấu trúc dữ liệu này cho các chuỗi, đặc biệt là các chuỗi dài được sử dụng trong trình soạn thảo.
Neil G

2
Dù sao, cảm ơn vì đã viết bài này. Tôi sẽ ghi nhớ nó nếu tôi cần cấu trúc dữ liệu này.
Neil G

11

Ngoài ra còn có mô-đun Blist chứa kiểu dữ liệu sắp xếp :

sortedset(iterable=(), key=None)

>>> from blist import sortedset
>>> my_set = sortedset([3,7,2,2])
sortedset([2, 3, 7]

5

Không hẳn là "vùng chứa được sắp xếp", nhưng bạn có thể quan tâm đến mô-đun bisect của thư viện tiêu chuẩn , "cung cấp hỗ trợ để duy trì danh sách theo thứ tự đã sắp xếp mà không cần phải sắp xếp danh sách sau mỗi lần chèn".


1

Có một heapqtrong thư viện tiêu chuẩn, nó không được sắp xếp chính xác, nhưng là loại. Cũng có một gói vỉ , nhưng nó không có trong thư viện tiêu chuẩn.


-2

Danh sách Python được sắp xếp theo thứ tự. Nếu bạn sắp xếp chúng, chúng vẫn như vậy. Trong Python 2.7, một OrderedDictkiểu đã được thêm vào để duy trì một từ điển có thứ tự rõ ràng.

Python cũng có các bộ (một tập hợp trong đó các thành viên phải là duy nhất), nhưng theo định nghĩa thì chúng không có thứ tự. Sắp xếp một tập hợp chỉ trả về a list.


8
Cảm ơn đã dành thời gian trả lời. OrderedDict được sắp xếp theo thứ tự chèn chứ không phải theo khóa tùy ý như vùng chứa được sắp xếp. bộ cũng không phải là một vùng chứa được sắp xếp.
Neil G

1
Có lẽ btree là thứ bạn đang tìm kiếm? stackoverflow.com/questions/628192#628432
jathanism

cảm ơn, btree chính xác là loại thứ tôi đang tìm kiếm. Tôi sẽ sử dụng Blist vì nó có trong MacPorts và có nhiều cấu trúc dữ liệu tiện dụng.
Neil G
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.