IT Share you

Python 세트가 해시되지 않는 이유는 무엇입니까?

shareyou 2020. 12. 6. 22:19
반응형

Python 세트가 해시되지 않는 이유는 무엇입니까?


Python에서 powerset 함수를 구현하는 방법을 자세히 설명하는 블로그 게시물을 우연히 발견했습니다. 그래서 저는 제 자신의 방식을 시도해 보았고, 세트는 해시 할 수 없기 때문에 파이썬은 분명히 세트를 가질 수 없다는 것을 발견했습니다. powerset의 정의는 세트의 집합이라는 것이기 때문에 이것은 짜증 스럽습니다. 실제 집합 연산을 사용하여 구현하고 싶었습니다.

>>> set([ set() ])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

Python 세트가 해시되지 않는 이유가 있습니까?


일반적으로 Python에서는 변경 불가능한 객체 만 해시 할 수 있습니다. 의 불변의 변형 set()- frozenset()- 해쉬이다.


변경 가능하기 때문입니다.

해시 할 수있는 경우 해시는 조용히 "무효"가 될 수 있으며 이는 해싱을 무의미하게 만듭니다.


Python 문서에서 :

hashable
객체는 수명 동안 변경되지 않는 해시 값 ( 해시 () 메서드 필요)이있는 경우 해시 가능하고 다른 객체와 비교할 수 있습니다 ( eq () 또는 cmp () 메서드 필요). 동일하게 비교되는 해시 가능한 객체는 동일한 해시 값을 가져야합니다.

해시 가능성은 이러한 데이터 구조가 내부적으로 해시 값을 사용하기 때문에 객체를 사전 키 및 집합 멤버로 사용할 수있게합니다.

파이썬의 모든 불변 내장 객체는 해시 가능하지만 (목록 또는 사전과 같은) 변경 가능한 컨테이너는 없습니다. 사용자 정의 클래스의 인스턴스 인 객체는 기본적으로 해시 할 수 있습니다. 그들은 모두 같지 않은 것을 비교하고 해시 값은 id ()입니다.


이것이 도움이되는 경우 ... 어떤 이유로 해시 할 수없는 것을 해시 가능한 등가물로 변환해야하는 경우 다음과 같이 할 수 있습니다.

from collections import Hashable, MutableSet, MutableSequence, MutableMapping

def make_hashdict(value):
    """
    Inspired by https://stackoverflow.com/questions/1151658/python-hashable-dicts
     - with the added bonus that it inherits from the dict type of value
       so OrderedDict's maintain their order and other subclasses of dict() maintain their attributes
    """
    map_type = type(value)

    class HashableDict(map_type):
        def __init__(self, *args, **kwargs):
            super(HashableDict, self).__init__(*args, **kwargs)
        def __hash__(self):
            return hash(tuple(sorted(self.items())))

    hashDict = HashableDict(value)

    return hashDict


def make_hashable(value):
    if not isinstance(value, Hashable):
        if isinstance(value, MutableSet):
            value = frozenset(value)
        elif isinstance(value, MutableSequence):
            value = tuple(value)
        elif isinstance(value, MutableMapping):
            value = make_hashdict(value)

        return value

my_set = set()
my_set.add(make_hashable(['a', 'list']))
my_set.add(make_hashable({'a': 1, 'dict': 2}))
my_set.add(make_hashable({'a', 'new', 'set'}))

print my_set

내 HashableDict 구현은 여기 에서 가장 간단하고 덜 엄격한 예제입니다 . 피클 링 및 기타 사항을 지원하는 고급 HashableDict가 필요한 경우 다른 많은 구현을 확인하십시오. 위의 버전에서는 원래 dict 클래스를 보존하여 OrderedDicts의 순서를 유지하고 싶었습니다. 또한 속성과 같은 액세스를 위해 여기 에서 AttrDict를 사용 합니다.

위의 예제는 어떤 식 으로든 권위있는 것이 아니며, 세트에 일부 항목을 저장하고 먼저 "해시 화"해야하는 유사한 문제에 대한 내 솔루션입니다.

참고 URL : https://stackoverflow.com/questions/6310867/why-arent-python-sets-hashable

반응형