Why aren't Python sets hashable?

后端 未结 4 1383

I stumbled across a blog post detailing how to implement a powerset function in Python. So I went about trying my own way of doing it, and discovered that Python apparently

4条回答
  •  天命终不由人
    2020-11-29 03:23

    In case this helps... if you really need to convert unhashable things into hashable equivalents for some reason you might do something like this:

    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
    

    My HashableDict implementation is the simplest and least rigorous example from here. If you need a more advanced HashableDict that supports pickling and other things, check the many other implementations. In my version above I wanted to preserve the original dict class, thus preserving the order of OrderedDicts. I also use AttrDict from here for attribute-like access.

    My example above is not in any way authoritative, just my solution to a similar problem where I needed to store some things in a set and needed to "hashify" them first.

提交回复
热议问题