1

I'm a relatively new Python (3) programmer. I have a need for a data structure which seems to combine features of collections.Counter, deque, and set, and was hoping someone with more experience could suggest the most "pythonic" approach.

I have a sparse collection of integer indexes, and need to maintain counts associated with each index -- like a Counter. But I also want to retain an implicit ordering between index:count pairs, so that I can e.g. remove the oldest one without knowing its index - like a deque. Finally I'd like to be able to conveniently check for whether an index is present, like a set. Lastly, in case it matters, I want to use rv_discrete from scypy.stats to select members with probabilty weighted by the count.

Any thoughts much appreciated.

JHD
  • 55
  • 4

1 Answers1

0

From your description, it sounds like an ordered counter should do most of that. The OrderedDict keeps track of insertion order and the Counter keeps track of the frequency of items.

Demo:

>>> from collections import OrderedDict, Counter
>>> class OrderedCounter(Counter, OrderedDict):
...     pass
>>>
>>> oc = OrderedCounter()
>>> oc[0] = 5
>>> oc[2] = 27
>>> oc
OrderedCounter({2: 27, 0: 5})
>>> oc.update({2:1, 0:6, 7:1})
>>> oc
OrderedCounter({2: 28, 0: 11, 7: 1})
>>> oc.popitem()
(7, 1)
>>> oc.popitem()
(2, 28)
>>> oc.popitem()
(0, 11)

You could get the first inserted key with oc.keys()[0].

timgeb
  • 76,762
  • 20
  • 123
  • 145