Collection Classes
Specialized collection classes with enhanced functionality beyond Python’s built-in collections.
attrdict
Six dictionary classes with special behaviors:
attrdict: Attribute-style access (dot notation)lazydict: Lazy evaluation of function valuesemptydict: Returns None for missing keysbidict: Bidirectional dictionary with inverse mappingMutableDict: Ordered dict with insert_before/insert_afterCaseInsensitiveDict: Case-insensitive key access
- class attrdict[source]
Bases:
dictA dictionary subclass that allows attribute-style access.
This is a dictionary that allows access to its keys as attributes (using dot notation) in addition to standard dictionary access methods.
Basic Usage:
>>> import copy >>> d = attrdict(x=10, y='foo') >>> d.x 10 >>> d['x'] 10 >>> d.y = 'baa' >>> d['y'] 'baa' >>> g = d.copy() >>> g.x = 11 >>> d.x 10 >>> d.z = 1 >>> d.z 1 >>> 'x' in d True >>> 'w' in d False >>> d.get('x') 10 >>> d.get('w')
Deep Copy Behavior:
>>> tricky = [d, g] >>> tricky2 = copy.copy(tricky) >>> tricky2[1].x 11 >>> tricky2[1].x = 12 >>> tricky[1].x 12 >>> righty = copy.deepcopy(tricky) >>> righty[1].x 12 >>> righty[1].x = 13 >>> tricky[1].x 12
Access Methods (handles
obj.get('attr'),obj['attr'], andobj.attr):>>> class A(attrdict): ... @property ... def x(self): ... return 1 >>> a = A() >>> a['x'] == a.x == a.get('x') True >>> a.get('b') >>> a['b'] Traceback (most recent call last): ... KeyError: 'b' >>> a.b Traceback (most recent call last): ... AttributeError: b
- get(key, default=None)[source]
- update(*args, **kwargs)[source]
- copy(**kwargs)[source]
- class lazydict[source]
Bases:
attrdictA dictionary where function values are lazily evaluated.
Functions stored as values are called with the dictionary as argument when the key is accessed, making them behave like computed properties.
Basic Usage:
>>> a = lazydict(a=1, b=2, c=lambda x: x.a+x.b) >>> a.c 3 >>> a.a = 99 >>> a.c # Recalculated with new value 101 >>> a.z = 1 >>> a.z 1
Instance Isolation (descriptors are not shared between instances):
>>> z = lazydict(a=2, y=4, f=lambda x: x.a*x.y) >>> z.b Traceback (most recent call last): ... AttributeError: b >>> z.c Traceback (most recent call last): ... AttributeError: c >>> z.f 8 >>> a.f Traceback (most recent call last): ... AttributeError: f
- class emptydict[source]
Bases:
attrdictA dictionary that returns None for non-existing keys without raising exceptions.
Similar to attrdict but returns None instead of raising KeyError or AttributeError when accessing non-existing keys.
Basic Usage:
>>> a = emptydict(a=1, b=2) >>> a.c == None True >>> a.b 2 >>> a['b'] 2 >>> 'c' in a False >>> 'b' in a True >>> a.get('b') 2 >>> a.get('c')
- class bidict(*args, **kwargs)[source]
Bases:
dictBidirectional dictionary that allows multiple keys with the same value.
Maintains an inverse mapping from values to lists of keys that enables bidirectional lookup.
Basic Usage:
>>> bd = bidict({'a': 1, 'b': 2}) >>> bd {'a': 1, 'b': 2} >>> bd.inverse {1: ['a'], 2: ['b']}
Multiple Keys with Same Value:
>>> bd['c'] = 1 >>> bd {'a': 1, 'b': 2, 'c': 1} >>> bd.inverse {1: ['a', 'c'], 2: ['b']}
Removing Keys Updates Inverse:
>>> del bd['c'] >>> bd {'a': 1, 'b': 2} >>> bd.inverse {1: ['a'], 2: ['b']} >>> del bd['a'] >>> bd {'b': 2} >>> bd.inverse {2: ['b']}
Changing Values Updates Inverse:
>>> bd['b'] = 3 >>> bd {'b': 3} >>> bd.inverse {2: [], 3: ['b']}
- inverse
- class MutableDict[source]
Bases:
dictAn ordered dictionary with additional insertion methods.
Extends the standard dictionary with methods to insert items before or after existing keys. Relies on Python 3.7+ dictionary implementation which preserves insertion order.
- insert_before(key, new_key, val)[source]
Insert new_key:value into dict before key.
Example:
>>> d = MutableDict({'a': 1, 'b': 2, 'c': 3}) >>> d.insert_before('b', 'x', 10) >>> list(d.keys()) ['a', 'x', 'b', 'c'] >>> d['x'] 10
- insert_after(key, new_key, val)[source]
Insert new_key:value into dict after key.
Example:
>>> d = MutableDict({'a': 1, 'b': 2, 'c': 3}) >>> d.insert_after('a', 'x', 10) >>> list(d.keys()) ['a', 'x', 'b', 'c'] >>> d['x'] 10
- class CaseInsensitiveDict(data=None, **kwargs)[source]
Bases:
MutableMappingA case-insensitive dictionary-like object.
Implements all methods and operations of
MutableMappingas well as dict’scopy. Also provideslower_items.All keys are expected to be strings. The structure remembers the case of the last key to be set, and
iter(instance),keys(),items()will contain case-sensitive keys. However, querying and contains testing is case insensitive:cid = CaseInsensitiveDict() cid[‘Accept’] = ‘application/json’ cid[‘aCCEPT’] == ‘application/json’ # True list(cid) == [‘Accept’] # True
For example,
headers['content-encoding']will return the value of a'Content-Encoding'response header, regardless of how the header name was originally stored.Note
If the constructor,
.update, or equality comparison operations are given keys that have equal.lower()values, the behavior is undefined.- lower_items()[source]
Like iteritems(), but with all lowercase keys.
Example:
>>> cid = CaseInsensitiveDict({'Content-Type': 'application/json'}) >>> list(cid.lower_items()) [('content-type', 'application/json')]
- copy()[source]
orderedset
OrderedSet: Set that preserves insertion order with unique elements.
Combines the uniqueness guarantee of sets with the ordering of lists.
- class OrderedSet(iterable=None)[source]
Bases:
MutableSetA set that maintains insertion order using a doubly linked list.
Provides set operations while preserving the order elements were added.
Note
Based on Raymond Hettinger’s recipe from ActiveState.
- Features:
Combines set behavior (unique elements) with list behavior (order preservation)
Supports all standard set operations (union, intersection, difference)
Maintains insertion order for iteration and representation
Example:
>>> s = OrderedSet('abracadaba') >>> t = OrderedSet('simsalabim') >>> (s | t) OrderedSet(['a', 'b', 'r', 'c', 'd', 's', 'i', 'm', 'l']) >>> (s & t) OrderedSet(['a', 'b']) >>> (s - t) OrderedSet(['r', 'c', 'd'])
- __init__(iterable=None)[source]
Initialize an OrderedSet with optional iterable.
Creates an empty ordered set or populates it from an iterable while preserving insertion order and removing duplicates.
- __len__()[source]
Return the number of elements in the set.
- Returns:
Count of unique elements.
- Return type:
- __contains__(key)[source]
Check if an element exists in the set.
- add(key)[source]
Add an element to the end of the set if not already present.
- discard(key)[source]
Remove an element from the set if present.
Does not raise an error if element is not found.
- __iter__()[source]
Iterate over elements in insertion order.
- Returns:
Iterator yielding elements in order of addition.
- Return type:
Iterator
- __reversed__()[source]
Iterate over elements in reverse insertion order.
- Returns:
Iterator yielding elements in reverse order.
- Return type:
Iterator
- pop(last=True)[source]
Remove and return an element from the set.
- __repr__()[source]
Return string representation of the set.
- Returns:
String showing class name and ordered elements.
- Return type:
heap
ComparableHeap: Heap queue with custom comparator key function.
Useful when you need priority queue behavior with custom ordering.
- class ComparableHeap(initial=None, key=<function ComparableHeap.<lambda>>)[source]
Bases:
objectHeap with custom key comparator.
Wraps heapq to add a keyed comparator function.
- Parameters:
initial (list) – Initial items for the heap.
key – Key function for comparison (default: identity).
Note
Algorithm from https://stackoverflow.com/questions/8875706/heapq-with-custom-compare-predicate
Example:
>>> from datetime import datetime >>> ch=ComparableHeap(initial=[ {'dtm':datetime(2017,1,1,12,10,59),'val':'one'}, {'dtm':datetime(2017,1,1,12,10,58),'val':'two'}], key=lambda f: f['dtm']) >>> ch.pop() {'dtm': datetime.datetime(2017, 1, 1, 12, 10, 58), 'val': 'two'} >>> ch.push({'val': 'three', 'dtm': datetime(2017,1,1,12,11,00)}) >>> ch.pop() {'dtm': datetime.datetime(2017, 1, 1, 12, 10, 59), 'val': 'one'}
- push(item)[source]
- pop()[source]