파이썬에는 사전이 있습니다. 주문 세트는 어떻습니까?
답변
이것에 대한 순서화 된 세트 (가능한 새로운 링크 ) 레시피가 있으며, 이는 Python 2 Documentation 에서 참조됩니다 . Py2.6 이상 및 3.0 이상에서 수정없이 실행됩니다. 인터페이스는 초기화를 목록으로 수행해야한다는 점을 제외하면 일반 세트와 거의 동일합니다.
OrderedSet([1, 2, 3])
이것은 MutableSet이므로에 대한 서명 .union
이 세트 의 서명 과 일치하지 않지만 __or__
비슷한 것을 포함하기 때문에 쉽게 추가 할 수 있습니다.
@staticmethod
def union(*sets):
union = OrderedSet()
union.union(*sets)
return union
def union(self, *sets):
for set in sets:
self |= set
답변
정렬 된 집합은 기능적으로 정렬 된 사전의 특수한 경우입니다.
사전의 키는 고유합니다. 따라서 정렬 된 사전에서 값을 무시하면 (예 : 값을 할당하여 None
) 본질적으로 정렬 된 세트를 갖습니다.
파이썬 3.1으로 있다 collections.OrderedDict
. 다음은 OrderedSet의 구현 예입니다. (단 몇 가지 방법을 정의 또는 오버라이드 (override) 할 필요가 있습니다 : collections.OrderedDict
와 collections.MutableSet
. 무거운 리프팅을 할)
import collections
class OrderedSet(collections.OrderedDict, collections.MutableSet):
def update(self, *args, **kwargs):
if kwargs:
raise TypeError("update() takes no keyword arguments")
for s in args:
for e in s:
self.add(e)
def add(self, elem):
self[elem] = None
def discard(self, elem):
self.pop(elem, None)
def __le__(self, other):
return all(e in other for e in self)
def __lt__(self, other):
return self <= other and self != other
def __ge__(self, other):
return all(e in self for e in other)
def __gt__(self, other):
return self >= other and self != other
def __repr__(self):
return 'OrderedSet([%s])' % (', '.join(map(repr, self.keys())))
def __str__(self):
return '{%s}' % (', '.join(map(repr, self.keys())))
difference = __sub__
difference_update = __isub__
intersection = __and__
intersection_update = __iand__
issubset = __le__
issuperset = __ge__
symmetric_difference = __xor__
symmetric_difference_update = __ixor__
union = __or__
답변
대답은 아니오이지만 동일한 목적 collections.OrderedDict
으로 키 (및 값 None
) 만으로 Python 표준 라이브러리에서 사용할 수 있습니다 .
업데이트 : Python 3.7 (및 CPython 3.6)부터 표준 dict
은 순서를 유지하도록 보장되며 보다 성능이 뛰어납니다 OrderedDict
. 그러나 이전 버전과의 호환성 및 특히 가독성을 위해 계속해서 사용하는 것이 OrderedDict
좋습니다.
다음 dict
은 주문을 유지하면서 중복 항목을 필터링하여 주문 세트를 에뮬레이트하는 주문 세트 로 사용하는 방법의 예입니다 . 사용 dict
클래스 메소드를 fromkeys()
다음 단순히 요청하는 딕셔너리를 만드는 keys()
다시.
>>> keywords = ['foo', 'bar', 'bar', 'foo', 'baz', 'foo']
>>> list(dict.fromkeys(keywords))
['foo', 'bar', 'baz']
답변
나는 당신에게 OrderedSet보다 하나 더 잘 할 수 있습니다 : boltons는 순서가 지정된 세트 일뿐 만 아니라 색인을 지원 하는 순수한 파이썬, 2/3 호환 IndexedSet
유형 을 가지고 있습니다 (목록과 마찬가지로).
간단하게 pip install boltons
(또는 setutils.py
코드베이스에 복사 ) 및를 가져옵니다 IndexedSet
.
>>> from boltons.setutils import IndexedSet
>>> x = IndexedSet(list(range(4)) + list(range(8)))
>>> x
IndexedSet([0, 1, 2, 3, 4, 5, 6, 7])
>>> x - set(range(2))
IndexedSet([2, 3, 4, 5, 6, 7])
>>> x[-1]
7
>>> fcr = IndexedSet('freecreditreport.com')
>>> ''.join(fcr[:fcr.index('.')])
'frecditpo'
모든 것이 독특하고 순서대로 유지됩니다. 전체 공개 : 나는 쓴 IndexedSet
,하지만 그 또한 의미 문제가 있는지 할 수 있습니다에게 버그 나 . 🙂
답변
PyPI 구현
다른 사람들은 파이썬 (아직)에 삽입 순서 보존 세트의 내장 구현이 없다고 지적했지만이 질문에는 PyPI 에서 무엇을 찾을 수 있는지에 대한 답변이 누락되었다고 생각합니다 .
패키지가 있습니다 :
- 순서 세트 (Python 기반)
- orderedset (Cython 기반)
- 컬렉션 확장
- oset (2012 년 마지막 업데이트)
이러한 구현 중 일부는 Raymond Hettinger가 ActiveState에 게시 한 레시피를 기반으로하며 여기에 다른 답변에서도 언급되어 있습니다.
약간의 차이
- 주문 세트 (버전 1.1)
- 장점 : 인덱스에 의해 조회를 위해 O (1) (예
my_set[5]
)
- 장점 : 인덱스에 의해 조회를 위해 O (1) (예
- oset (버전 0.1.3)
- 장점 : O (1)
remove(item)
- 단점 : 인덱스 별 조회의 경우 분명히 O (n)
- 장점 : O (1)
모두 구현은 O (1)에 대한이 add(item)
와 __contains__(item)
( item in my_set
)를.
답변
정렬 된 순서를 유지하기 위해 정렬 된 집합을 사용하는 경우 PyPI에서 정렬 된 집합 구현을 사용해보십시오. sortedcontainers의 모듈은 제공 SortedSet의를 바로이 목적을 위해. 몇 가지 장점 : 순수 Python, 빠른 C 구현, 100 % 단위 테스트 적용 범위, 스트레스 테스트 시간.
pip를 사용하면 PyPI에서 쉽게 설치할 수 있습니다.
pip install sortedcontainers
할 수없는 경우 오픈 소스 리포지토리pip install
에서 sortedlist.py 및 sortedset.py 파일을 풀다운하면 됩니다.
설치 한 후에는 간단하게 다음을 수행 할 수 있습니다.
from sortedcontainers import SortedSet
help(SortedSet)
sortedcontainers 모듈은 여러 대체 구현과 성능 비교 를 유지합니다 .
Python의 bag 데이터 유형에 대한 질문 에는 bag을 효율적으로 구현하는 데 사용할 수 있는 SortedList 데이터 유형이 있습니다.
답변
코드에서 이미 팬더를 사용중인 경우이 기사에Index
표시된 것처럼 해당 객체는 정렬 된 세트처럼 동작 합니다.
기사의 예 :
indA = pd.Index([1, 3, 5, 7, 9])
indB = pd.Index([2, 3, 5, 7, 11])
indA & indB # intersection
indA | indB # union
indA - indB # difference
indA ^ indB # symmetric difference