2012-04-16 3 views
31

중복 요소를 포함 할 수있는 "집합"을 표현하는 표준 방법이 있습니까?중복/반복 요소가있는 Python "set"

필자가 이해 하듯이, 세트에는 정확하게 하나 또는 하나의 요소가 있습니다. 나는 어떤 기능을 원한다.

저는 현재 요소를 키로 사용하고 값을 수량으로 사용하는 사전을 사용하고 있습니다.하지만 이는 여러 가지 이유로 잘못된 것 같습니다.

동기 부여 : 나는 그런 수집을위한 많은 응용이 있다고 믿습니다. 예를 들어, 좋아하는 색상에 대한 설문 조사는 다음과 같이 나타낼 수 있습니다. survey = [ 'blue', 'red', 'blue', 'green']

여기는 순서에 상관하지 않지만 수량에 대해. 내가 좋아하는 일을 할 :

survey.add('blue') 
# would give survey == ['blue', 'red', 'blue', 'green', 'blue'] 

... 어쩌면

survey.remove('blue') 
# would give survey == ['blue', 'red', 'green'] 

주 : 예, 수집 이런 종류의 올바른 용어가 아니다 설정합니다. 더 정확한 정보가 있습니까?

코스 목록이 작동하지만 필요한 컬렉션이 정렬되지 않았습니다. 세트를 명명하는 메소드가 나에게 더 적절하다고 생각하지는 않는다.

+0

이유를 설명하면 도움이 될 수 있습니다. – jamylak

+2

중복이 필요한 경우 정의에 의해 '설정'되지 않습니다. 당신이 원하는 것을 보여줄 수 있습니까? 아마도 적절한 컨테이너 또는 데이터 유형을 제안 할 수 있습니까? –

+2

예, 이것을 "목록"이라고합니다. – georg

답변

30

multiset을 찾고 있습니다.

파이썬의 가장 가까운 데이터 형식 collections.Counter입니다 :

Counter는 해쉬 객체를 카운트하는 dict 서브 클래스입니다. 요소가 사전 키로 저장되고 개수가 사전 값으로 저장되는 것은 순서가 지정되지 않은 모음 입니다. 카운트는 0 또는 음수 카운트를 포함하는 임의의 정수 값인 이 될 수 있습니다. Counter 클래스 은 다른 언어의 가방이나 다중 세트와 유사합니다.multiset의 실제의 구현에

는 pypi의 데이터 구조의 패키지에서 bag 클래스를 사용한다. 이것은 파이썬 3 전용입니다. Python 2가 필요한 경우 here은 Python 2.4 용으로 작성된 bag의 제조법입니다.

+3

컬렉션의 차이점은 무엇입니까? 카운터와 피피의 가방은 무엇입니까? – max

+0

파이썬 2.7.6에서 가방을 실행할 수 있습니다. 이유가 무엇입니까? – Zen

+5

큰 차이점은 다음과 같습니다. len (counter_obj)는 고유 한 요소의 수를 제공하지만 멀티 세트에서 기대하는 요소의 총 수는 제공하지 않습니다. 그러나 집합과 마찬가지로 유니온 및 교차점과 같은 다른 모든 작업을 수행 할 수 있습니다. – Phani

11

요소/개수가있는 dict로 접근하는 것이 나에게 좋을 것 같습니다. 아마도 더 많은 기능이 필요할 것입니다. collections.Counter을 살펴보십시오.

  • 요소가 존재하고 현재의 카운트 회수가
  • counter.elements() 모두 함께리스트 같다 (element in listlist.count(element)보다 빠른)는 다른 카운터,
  • 쉬운 조작 조합/차분 중복 여부 O (1) 시험
-2

중복이 필요하면 목록을 사용하고 세트로 작동해야 할 때 세트로 변환하십시오.

+1

OP가 멀티 세트를 찾고 목록을 세트로 변경했을 가능성이 큽니다 중복. – ComputerFellow

+0

편집하기 전에이 답변을 게시했습니다. 내 접근 방식은 집합을 원본 목록의보기로만 사용합니다. –

0

"숫자"요소에 액세스하려는 경우 일반 list을 사용하고 list.count(element)을 사용할 수 있습니다.

my_list = [1, 1, 2, 3, 3, 3] 

my_list.count(1) # will return 2 
0

파이썬 다중 세트 구현은 정렬 된 목록 데이터 구조를 사용합니다. PyPI에는 몇 가지 구현이 있습니다. 하나의 옵션은 add, removecontains과 같은 집합 방법을 효율적으로 구현하는 SortedList 데이터 유형을 구현하는 sortedcontainers 모듈입니다. sortedcontainers 모듈은 pure-Python, 빠른 as-C 구현 (더 빠름)으로 구현되며 100 % 단위 테스트 적용 범위와 스트레스 테스트 시간을 갖습니다.

설치 PyPI에서 쉽게 :

pip install sortedcontainers 

당신이 단순히 아래로 open-source repository에서 sortedlist.py 파일을 당기지 pip install 할 수 있습니다.

는 것 세트로 사용

from sortedcontainers import SortedList 
survey = SortedList(['blue', 'red', 'blue', 'green']] 
survey.add('blue') 
print survey.count('blue') # "3" 
survey.remove('blue') 

sortedcontainers 모듈은 다른 인기 구현과 함께 performance comparison을 유지합니다.

0

은 무엇 당신이 찾고있는 것은 참으로 multiset (또는 가방), 반드시 고유 요소의 모음 (을 설정 중복을 포함하지 않는 반면에)입니다.

multisets에 대한 구현은 https://github.com/mlenzen/collections-extended (Pypy의 collections extended 모듈)입니다.

멀티 세트의 데이터 구조는 bag입니다. bagcollections 모듈의 Set 클래스의 하위 클래스이며 요소의 다중성을 추적하는 추가 사전이 있습니다. 각 요소의 발생 횟수가 가방의 사전 최신 상태로 유지되기 때문에

class _basebag(Set): 
    """ 
    Base class for bag and frozenbag. Is not mutable and not hashable, so there's 
    no reason to use this instead of either bag or frozenbag. 
    """ 
    # Basic object methods 

    def __init__(self, iterable=None): 
     """Create a new basebag. 

     If iterable isn't given, is None or is empty then the bag starts empty. 
     Otherwise each element from iterable will be added to the bag 
     however many times it appears. 

     This runs in O(len(iterable)) 
     """ 
     self._dict = dict() 
     self._size = 0 
     if iterable: 
      if isinstance(iterable, _basebag): 
       for elem, count in iterable._dict.items(): 
        self._inc(elem, count) 
      else: 
       for value in iterable: 
        self._inc(value) 

bag위한 좋은 방법은 (목록의 Counter 유사) nlargest, 즉 엄청나게 빠른 모든 요소의 다중도를 반환 :

>>> b=bag(random.choice(string.ascii_letters) for x in xrange(10)) 
>>> b.nlargest() 
[('p', 2), ('A', 1), ('d', 1), ('m', 1), ('J', 1), ('M', 1), ('l', 1), ('n', 1), ('W', 1)] 
>>> Counter(b) 
Counter({'p': 2, 'A': 1, 'd': 1, 'm': 1, 'J': 1, 'M': 1, 'l': 1, 'n': 1, 'W': 1})