An implementation of a multiset data structure with both mutable and immutable variants supporting all standard set operations.
—
Mathematical set operations for multisets supporting both multiset and regular set operands. All operations preserve multiset semantics while maintaining compatibility with Python's built-in set operations.
Union operations combine multisets by taking the maximum multiplicity of each element across all operands.
def union(self, *others) -> BaseMultiset:
"""
Return a new multiset containing elements from this multiset and all others.
Takes maximum multiplicity for each element.
Parameters:
- *others: Iterables or mappings to union with
Returns:
New multiset with union of all inputs
"""
def __or__(self, other) -> BaseMultiset:
"""Union using | operator."""
def __ror__(self, other) -> BaseMultiset:
"""Reverse union using | operator."""Usage Examples:
from multiset import Multiset
ms1 = Multiset('aab') # {'a': 2, 'b': 1}
ms2 = Multiset('bcc') # {'b': 1, 'c': 2}
# Union takes maximum multiplicities
result = ms1.union(ms2) # {'a': 2, 'b': 1, 'c': 2}
result = ms1 | ms2 # Same result using operator
# Union with regular set
result = ms1 | {'x', 'y'} # {'a': 2, 'b': 1, 'x': 1, 'y': 1}Intersection operations return elements common to all operands with minimum multiplicities.
def intersection(self, *others) -> BaseMultiset:
"""
Return a new multiset containing elements common to all inputs.
Takes minimum multiplicity for each element.
Parameters:
- *others: Iterables or mappings to intersect with
Returns:
New multiset with intersection of all inputs
"""
def __and__(self, other) -> BaseMultiset:
"""Intersection using & operator."""
def __rand__(self, other) -> BaseMultiset:
"""Reverse intersection using & operator."""Usage Examples:
ms1 = Multiset('aaab') # {'a': 3, 'b': 1}
ms2 = Multiset('aabb') # {'a': 2, 'b': 2}
# Intersection takes minimum multiplicities
result = ms1.intersection(ms2) # {'a': 2, 'b': 1}
result = ms1 & ms2 # Same result using operatorDifference operations remove elements of other operands from the multiset.
def difference(self, *others) -> BaseMultiset:
"""
Return a new multiset with elements from this multiset that are not in others.
Subtracts multiplicities of elements found in others.
Parameters:
- *others: Iterables or mappings to subtract
Returns:
New multiset with elements removed
"""
def __sub__(self, other) -> BaseMultiset:
"""Difference using - operator."""
def __rsub__(self, other) -> BaseMultiset:
"""Reverse difference using - operator."""Usage Examples:
ms1 = Multiset('aaab') # {'a': 3, 'b': 1}
ms2 = Multiset('ab') # {'a': 1, 'b': 1}
# Difference subtracts multiplicities
result = ms1.difference(ms2) # {'a': 2}
result = ms1 - ms2 # Same result using operatorSymmetric difference returns elements that are in either multiset but not in both.
def symmetric_difference(self, other) -> BaseMultiset:
"""
Return a new multiset with elements in either this multiset or other but not both.
Takes absolute difference of multiplicities.
Parameters:
- other: Iterable or mapping to compare with
Returns:
New multiset with symmetric difference
"""
def __xor__(self, other) -> BaseMultiset:
"""Symmetric difference using ^ operator."""
def __rxor__(self, other) -> BaseMultiset:
"""Reverse symmetric difference using ^ operator."""Usage Examples:
ms1 = Multiset('aaab') # {'a': 3, 'b': 1}
ms2 = Multiset('aabb') # {'a': 2, 'b': 2}
# Symmetric difference takes absolute difference
result = ms1.symmetric_difference(ms2) # {'a': 1, 'b': 1}
result = ms1 ^ ms2 # Same result using operatorCombination operations sum multiplicities of elements across all operands.
def combine(self, *others) -> BaseMultiset:
"""
Return a new multiset combining this multiset with others.
Sums multiplicities of all elements.
Parameters:
- *others: Iterables or mappings to combine with
Returns:
New multiset with summed multiplicities
"""
def __add__(self, other) -> BaseMultiset:
"""Combination using + operator."""
def __radd__(self, other) -> BaseMultiset:
"""Reverse combination using + operator."""Usage Examples:
ms1 = Multiset('aab') # {'a': 2, 'b': 1}
ms2 = Multiset('abb') # {'a': 1, 'b': 2}
# Combination sums multiplicities
result = ms1.combine(ms2) # {'a': 3, 'b': 3}
result = ms1 + ms2 # Same result using operatorScaling operations multiply all multiplicities by a factor.
def times(self, factor: int) -> BaseMultiset:
"""
Return a new multiset with all multiplicities scaled by factor.
Parameters:
- factor: Integer scaling factor (must be non-negative)
Returns:
New multiset with scaled multiplicities
Raises:
ValueError: If factor is negative
"""
def __mul__(self, factor: int) -> BaseMultiset:
"""Scaling using * operator."""
def __rmul__(self, factor: int) -> BaseMultiset:
"""Reverse scaling using * operator."""Usage Examples:
ms = Multiset('aab') # {'a': 2, 'b': 1}
# Scale multiplicities
result = ms.times(3) # {'a': 6, 'b': 3}
result = ms * 3 # Same result using operator
result = 2 * ms # {'a': 4, 'b': 2}Test relationships between multisets and other collections.
def isdisjoint(self, other) -> bool:
"""
Return True if multiset has no elements in common with other.
Parameters:
- other: Iterable or mapping to compare with
Returns:
True if no common elements exist
"""
def issubset(self, other) -> bool:
"""
Return True if all elements in this multiset are contained in other
with sufficient multiplicities.
Parameters:
- other: Iterable or mapping to compare with
Returns:
True if this is a subset of other
"""
def issuperset(self, other) -> bool:
"""
Return True if all elements in other are contained in this multiset
with sufficient multiplicities.
Parameters:
- other: Iterable or mapping to compare with
Returns:
True if this is a superset of other
"""
def __le__(self, other) -> bool:
"""Subset test using <= operator."""
def __lt__(self, other) -> bool:
"""Proper subset test using < operator."""
def __ge__(self, other) -> bool:
"""Superset test using >= operator."""
def __gt__(self, other) -> bool:
"""Proper superset test using > operator."""Usage Examples:
ms1 = Multiset('ab') # {'a': 1, 'b': 1}
ms2 = Multiset('aabb') # {'a': 2, 'b': 2}
ms3 = Multiset('cd') # {'c': 1, 'd': 1}
# Relationship tests
ms1.isdisjoint(ms3) # True (no common elements)
ms1.issubset(ms2) # True (ms1 ⊆ ms2)
ms2.issuperset(ms1) # True (ms2 ⊇ ms1)
# Using operators
ms1 <= ms2 # True (subset)
ms1 < ms2 # True (proper subset)
ms2 >= ms1 # True (superset)
ms2 > ms1 # True (proper superset)def __eq__(self, other) -> bool:
"""
Return True if multisets have identical elements and multiplicities.
Parameters:
- other: Object to compare with
Returns:
True if multisets are equal
"""
def __ne__(self, other) -> bool:
"""Return True if multisets are not equal."""Usage Examples:
ms1 = Multiset('aab')
ms2 = Multiset(['a', 'a', 'b'])
ms3 = Multiset('abb')
ms1 == ms2 # True (same elements and multiplicities)
ms1 != ms3 # True (different multiplicities)Install with Tessl CLI
npx tessl i tessl/pypi-multiset