Extra Python Collections - bags (multisets) and setlists (ordered sets)
npx @tessl/cli install tessl/pypi-collections-extended@2.0.0A comprehensive Python library providing extended collections that fill gaps in the standard library. Collections Extended offers specialized data structures including bags (multisets) for counting elements with duplicates, setlists (ordered sets) that maintain both uniqueness and insertion order, bijections for one-to-one mappings with inverse lookups, RangeMaps for mapping ranges to values, and IndexedDicts for ordered mappings with index-based access.
pip install collections-extendedfrom collections_extended import bag, frozenbag, setlist, frozensetlist, bijection, IndexedDict, RangeMapAll collection types:
from collections_extended import (
Collection, # Standard Collection ABC (re-exported)
Bag, bag, frozenbag, # Bags (base class and implementations)
SetList, setlist, frozensetlist, # Setlists (base class and implementations)
bijection, # One-to-one mappings
IndexedDict, # Ordered mappings with index access
RangeMap, MappedRange, # Range mappings
collection # Factory function
)from collections_extended import bag, setlist, bijection, RangeMap, IndexedDict
from datetime import date
# Bags - multisets that count duplicates
b = bag('abracadabra')
print(b.count('a')) # 5
b.remove('a')
print(b.count('a')) # 4
print('a' in b) # True
# Setlists - ordered sets maintaining insertion order
sl = setlist('abracadabra')
print(sl) # setlist(('a', 'b', 'r', 'c', 'd'))
print(sl[3]) # 'c'
print(sl.index('d')) # 4
# Bijections - one-to-one mappings with inverse lookup
bij = bijection({'a': 1, 'b': 2, 'c': 3})
print(bij.inverse[2]) # 'b'
bij['a'] = 2
print(bij == bijection({'a': 2, 'c': 3})) # True
# RangeMaps - map ranges to values
version = RangeMap()
version[date(2017, 10, 20): date(2017, 10, 27)] = '0.10.1'
version[date(2017, 10, 27): date(2018, 2, 14)] = '1.0.0'
version[date(2018, 2, 14):] = '1.0.1'
print(version[date(2017, 10, 24)]) # '0.10.1'
# IndexedDict - ordered mapping with index access
idict = IndexedDict()
idict['a'] = "A"
idict['b'] = "B"
idict['c'] = "C"
print(idict.get(key='a')) # 'A'
print(idict.get(index=2)) # 'C'
print(idict.index('b')) # 1Collections Extended provides five main collection types, each with mutable and immutable variants:
The library follows Python collection protocols and provides both mutable and frozen (hashable) variants for data structure immutability when needed.
Multisets that track element counts with duplicates allowed. Support mathematical set operations, counting, and statistical operations on collections with repeated elements.
class bag:
def __init__(self, iterable=None): ...
def count(self, value): ...
def add(self, elem): ...
def remove(self, elem): ...
def discard(self, elem): ...
def unique_elements(self): ...
def counts(self): ...
class frozenbag(bag, Hashable):
def __hash__(self): ...Ordered sets maintaining both uniqueness and insertion order. Combine list-like indexing with set-like uniqueness constraints and operations.
class setlist:
def __init__(self, iterable=None, raise_on_duplicate=False): ...
def append(self, value): ...
def insert(self, index, value): ...
def index(self, value, start=0, end=None): ...
def count(self, value): ...
class frozensetlist(setlist, Hashable):
def __hash__(self): ...One-to-one mappings with automatic inverse relationship maintenance. Enable efficient bidirectional lookups and enforce uniqueness in both keys and values.
class bijection:
def __init__(self, iterable=None, **kwargs): ...
@property
def inverse(self): ...
def copy(self): ...
def clear(self): ...Bijections and One-to-One Mappings
Mappings from continuous ranges to values using efficient interval-based storage. Support slice notation and range operations for time series, version ranges, and interval data.
class RangeMap:
def __init__(self, iterable=None, default_value=NOT_SET): ...
def set(self, value, start=None, stop=None): ...
def get(self, key, restval=None): ...
def ranges(self, start=None, stop=None): ...
class MappedRange:
def __init__(self, start, stop, value): ...
start: Any
stop: Any
value: AnyOrdered mappings with both key-based and index-based access. Maintain insertion order while providing efficient positional access and manipulation.
class IndexedDict:
def __init__(self, iterable=None, **kwargs): ...
def get(self, key=NOT_SET, index=NOT_SET, default=NOT_SET): ...
def pop(self, key=NOT_SET, index=NOT_SET, default=NOT_SET): ...
def index(self, key): ...
def key(self, index): ...Utility function that returns the appropriate collection type based on specified properties.
def collection(iterable=None, mutable=True, ordered=False, unique=False):
"""Return a Collection with the specified properties.
Args:
iterable: Collection to instantiate new collection from
mutable: Whether the new collection is mutable
ordered: Whether the new collection is ordered
unique: Whether the new collection contains only unique values
Returns:
Appropriate collection type based on parameters
"""