defaultdict of fixed-length buffers


In [1]:
from collections import deque

In [2]:
# Buffer with maximum length of 3
buffer = deque([], 3)

In [3]:
buffer


Out[3]:
deque([])

In [4]:
buffer.append(1)

In [5]:
buffer


Out[5]:
deque([1])

In [7]:
buffer.append(2)
buffer.append(3)

In [8]:
buffer


Out[8]:
deque([1, 2, 3])

In [9]:
buffer.append(4)

In [10]:
# First item is kicked out
buffer


Out[10]:
deque([2, 3, 4])

Now let's say we want a number of these buffers that we want to reference via a dictionary

defaultdict


In [11]:
from collections import defaultdict

defaultdict takes a callable that'll be used as the default value if the requested key doesn't exist in the dict


In [12]:
x = defaultdict(list)

In [15]:
x['a']


Out[15]:
[]

In [16]:
x['b'].append(2)

In [17]:
x


Out[17]:
defaultdict(list, {'a': [], 'b': [2]})

The default value is generated upon the first access

partial

partial allows you to partially apply a function. In our case it's nice since we can create a callable for defaultdict.


In [19]:
from functools import partial

In [22]:
x = partial(deque, maxlen=3)
x


Out[22]:
functools.partial(<class 'collections.deque'>, maxlen=3)

In [23]:
x()


Out[23]:
deque([])

Putting the two together


In [24]:
x = defaultdict(partial(deque, maxlen=3))

In [25]:
x


Out[25]:
defaultdict(functools.partial(<class 'collections.deque'>, maxlen=3), {})

In [26]:
x['a']


Out[26]:
deque([])

In [27]:
x


Out[27]:
defaultdict(functools.partial(<class 'collections.deque'>, maxlen=3),
            {'a': deque([])})

In [28]:
x['a'].append(1)
x['a'].append(2)

In [29]:
x


Out[29]:
defaultdict(functools.partial(<class 'collections.deque'>, maxlen=3),
            {'a': deque([1, 2])})

In [30]:
x['a'].append(3)
x['a'].append(4)

In [31]:
x


Out[31]:
defaultdict(functools.partial(<class 'collections.deque'>, maxlen=3),
            {'a': deque([2, 3, 4])})

In [32]:
x['b']


Out[32]:
deque([])

In [33]:
x['b'].append(1)
x['b'].append(2)
x['b'].append(3)
x


Out[33]:
defaultdict(functools.partial(<class 'collections.deque'>, maxlen=3),
            {'a': deque([2, 3, 4]), 'b': deque([1, 2, 3])})

In [34]:
x['b'].append(4)

In [35]:
x


Out[35]:
defaultdict(functools.partial(<class 'collections.deque'>, maxlen=3),
            {'a': deque([2, 3, 4]), 'b': deque([2, 3, 4])})