Unordered list as dict key
What you seem to require is a way to use unordered pairs of key-amount as keys. A frozenset
is probably the way to go, although you will have to create it out of the items
of the Counter
and not its keys
.
foo = Counter(['bar', 'shoo', 'bar'])
tmp = {}
tmp[frozenset(foo.items())] = 5
# tmp: {frozenset({('bar', 2), ('shoo', 1)}): 5}
If this is satisfying, you could implement this transformation by defining you own mapping type like so:
from collections import Counter
class CounterDict:
def __init__(self):
self.data = {}
def __setitem__(self, key, value):
if isinstance(key, Counter):
self.data[frozenset(key.items())] = value
else:
raise TypeError
def __getitem__(self, key):
if isinstance(key, Counter):
return self.data[frozenset(key.items())]
else:
raise TypeError
foo = Counter(['bar', 'shoo', 'bar'])
tmp = CounterDict()
tmp[foo] = 42
tmp[foo] # 42
You could make this implementation richer by making CounterDict
a subclass of collections.UserDict
.
There are a couple of things you could do. One is to sort the list and convert the result to a tuple
. That will work fine for small lists.
If you have large lists (with duplicates), you could convert it into a frozenset
whose elements are tuples which are (word, count) pairs. So for the example, if your list is ['bar', 'shoo', 'bar']
, you would have frozenset({('bar', 2), ('shoo', 1)})
.
You could construct this by using Counter
, or else just construct a dict
of word: count
entries, then convert the entries to tuples and construct a frozenset
from them.
Both of these would be hashable, and support duplicate elements in the original list.