Python의 표준 라이브러리에 정렬 된 컨테이너가없는 이유는 무엇입니까?


83

정렬 된 컨테이너가 Python에 추가되지 않도록하는 Python 설계 결정 (PEP)이 있습니까?

( OrderedDict은 삽입 순서로 정렬되어 있으므로 정렬 된 컨테이너가 아닙니다.)


1
collections.OrderedDict처럼?
utdemir

1
더 빠릅니다. 해시 맵의 경우 O (1) 대 정렬 된 집합의 경우 O (log n).
vartec

19
@utdmr : OrderedDict는 정렬 된 컨테이너와 같은 임의의 키가 아닌 삽입 순서에 따라 정렬됩니다.
Neil G

1
@ Hi-Angel 아니요, 그것은 분류 된 컨테이너가 의미하는 것이 아닙니다 .
닐 G

1
"정렬 된 컨테이너는 삽입시 요소를 정렬하는 컨테이너입니다". 정확히는 아닙니다. 정렬 된 컨테이너는 인터페이스가 (임의의 키에 따라) 반복 및 검색을 효율적으로 정렬 한 컨테이너라고 말하고 싶습니다. 당신의 오해는 당신의 비정상적인 정의에서 비롯됩니다.
Neil G

답변:


77

그것은 Guido의 의식적인 디자인 결정입니다 (그는 collections모듈 추가에 대해 다소 주저했습니다 ). 그의 목표는 응용 프로그램을위한 데이터 유형 선택과 관련하여 "한 가지 분명한 방법"을 유지하는 것입니다.

기본 개념은 사용자가 내장 유형이 문제에 대한 올바른 해결책이 아니라는 것을 인식 할만큼 충분히 정교하다면 적절한 타사 라이브러리를 찾는 작업에 달려 있다는 것입니다.

list + sorting, list + heapq 및 list + bisect가 본질적으로 정렬 된 데이터 구조에 의존하는 많은 사용 사례를 다루고 blist와 같은 패키지가 존재한다는 점을 감안할 때이 공간에 더 많은 복잡성을 추가 할 큰 드라이브는 없습니다. 표준 라이브러리.

어떤면에서 그것은 표준 라이브러리에 다차원 배열이 없다는 사실과 유사하며 대신 NumPy 사람들에게 그 작업을 넘깁니다.


2
감사합니다. 저는이 디자인 결정의 동기를 찾고있었습니다. 이것이 제가 찾던 바로 그 종류의 대답입니다. 내 처음 본능은 이런 식으로 일을하는 것이 아니었지만, 그 주장은 매우 설득력이 있습니다.
Neil G

collections.Counter정렬 된 세트로 사용할 수 있습니다. 효율적이지 않을 수 있습니다.
coderek 2017

1
@coderek : collections.Counter정렬되지 않았으며 정렬 된 집합을 나타내는 데 적합하지 않습니다.
user2357112 모니카 지원

그러나 적어도 내장 사전이 정렬되어서는 안됩니까? 요소에 대한 빠른 액세스를 제공하기 위해 사전을 정렬하여 저장해야합니다.이 사전을 반복 할 때 여전히 정렬되지 않은 항목으로 끝나는 것이 이상하게 보입니다.
Hi-Angel

1
@ Hi-Angel dict은 해시 테이블입니다.
Neil G

82

정렬 된 목록, dict 및 집합 유형을 구현 하는 python sortedcontainers 모듈 도 있습니다. blist와 매우 유사하지만 pure-Python으로 구현 되며 대부분의 경우 더 빠릅니다 .

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

또한 다른 패키지에는 일반적이지 않은 기능이 있습니다.

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

면책 조항 : 저는 sortedcontainers 모듈의 작성자입니다.


1
좋은! 기본 저장소가 로프 임을 지정하도록 문서를 업데이트하는 것을 고려할 수 있습니다 .
Neil G

1
@NeilG 감사합니다! 커플 노트 : blist는 순수한 파이썬으로 작성되지 않았습니다. 정렬 된 집합, 목록 및 dict 유형은 C에서 구현 된 B +-트리 인 blist 유형을 기반으로합니다. 또한 기본 구조는 실제로 로프가 아닙니다. B +-트리와 더 비슷하지만 한 수준의 노드 만 있습니다.
GrantJ

3
실제로 big-O가 오해의 소지가있는 방법을 보여주는 좋은 예입니다. 아마도 1 조 요소 정도의 속도가 느려질 것이지만 대부분의 사람들은 그것에 대해 걱정할 수있는 테라 바이트의 메모리가 없습니다. 수십억 개의 요소로 테스트했으며 C 구현만큼 빠릅니다. 또한 이러한 간단한 목록 기반 구조를 유지함으로써 훨씬 적은 메모리를 사용합니다.
GrantJ 2014 년

1
네, 물론입니다. 문자열, 특히 편집기에서 사용되는 긴 문자열에 대해 이러한 종류의 데이터 구조를 사용하여 정당화하는 데 사용하는 것과 동일한 인수입니다.
Neil G

2
어쨌든이 글을 써 주셔서 감사합니다. 이 데이터 구조가 필요한 경우 염두에 두겠습니다.
Neil G

11

도있다 blist의 포함 모듈 의 SortedSet의 데이터 유형 :

sortedset(iterable=(), key=None)

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

5

정확히 "정렬 된 컨테이너"는 아니지만 "삽입 후 목록을 정렬 할 필요없이 정렬 된 순서로 목록을 유지하는 지원을 제공하는" 표준 라이브러리의 bisect 모듈에 관심이있을 수 있습니다 .


1

a는있다 heapq표준 라이브러리에서, 정확히하지만, 가지, 정렬되지 않습니다. 거기에 또한 blist의 패키지는하지만, 표준 라이브러리에 없습니다.


-2

파이썬 목록은 정렬되어 있습니다. 정렬하면 그대로 유지됩니다. Python 2.7에서는 OrderedDict명시 적으로 정렬 된 사전을 유지하기 위해 유형이 추가되었습니다.

파이썬에는 또한 집합 (멤버가 고유해야하는 컬렉션)이 있지만 정의에 따라 순서가 지정되지 않습니다. 집합을 정렬하면 list.


8
시간을내어 답변 해 주셔서 감사합니다. OrderedDict는 정렬 된 컨테이너와 같은 임의의 키가 아닌 삽입 순서에 따라 정렬됩니다. set도 정렬 된 컨테이너가 아닙니다.
Neil G

1
btree는 아마도 당신이 찾고있는 것일까 요? stackoverflow.com/questions/628192#628432
jathanism

감사합니다, btree는 제가 찾던 바로 그 종류입니다. 나는 그것이 MacPorts에 있고 편리한 데이터 구조를 가지고 있기 때문에 blist로 갈 것입니다.
Neil G
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.