0
# Set Operations
1
2
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.
3
4
## Capabilities
5
6
### Union Operations
7
8
Union operations combine multisets by taking the maximum multiplicity of each element across all operands.
9
10
```python { .api }
11
def union(self, *others) -> BaseMultiset:
12
"""
13
Return a new multiset containing elements from this multiset and all others.
14
Takes maximum multiplicity for each element.
15
16
Parameters:
17
- *others: Iterables or mappings to union with
18
19
Returns:
20
New multiset with union of all inputs
21
"""
22
23
def __or__(self, other) -> BaseMultiset:
24
"""Union using | operator."""
25
26
def __ror__(self, other) -> BaseMultiset:
27
"""Reverse union using | operator."""
28
```
29
30
**Usage Examples:**
31
32
```python
33
from multiset import Multiset
34
35
ms1 = Multiset('aab') # {'a': 2, 'b': 1}
36
ms2 = Multiset('bcc') # {'b': 1, 'c': 2}
37
38
# Union takes maximum multiplicities
39
result = ms1.union(ms2) # {'a': 2, 'b': 1, 'c': 2}
40
result = ms1 | ms2 # Same result using operator
41
42
# Union with regular set
43
result = ms1 | {'x', 'y'} # {'a': 2, 'b': 1, 'x': 1, 'y': 1}
44
```
45
46
### Intersection Operations
47
48
Intersection operations return elements common to all operands with minimum multiplicities.
49
50
```python { .api }
51
def intersection(self, *others) -> BaseMultiset:
52
"""
53
Return a new multiset containing elements common to all inputs.
54
Takes minimum multiplicity for each element.
55
56
Parameters:
57
- *others: Iterables or mappings to intersect with
58
59
Returns:
60
New multiset with intersection of all inputs
61
"""
62
63
def __and__(self, other) -> BaseMultiset:
64
"""Intersection using & operator."""
65
66
def __rand__(self, other) -> BaseMultiset:
67
"""Reverse intersection using & operator."""
68
```
69
70
**Usage Examples:**
71
72
```python
73
ms1 = Multiset('aaab') # {'a': 3, 'b': 1}
74
ms2 = Multiset('aabb') # {'a': 2, 'b': 2}
75
76
# Intersection takes minimum multiplicities
77
result = ms1.intersection(ms2) # {'a': 2, 'b': 1}
78
result = ms1 & ms2 # Same result using operator
79
```
80
81
### Difference Operations
82
83
Difference operations remove elements of other operands from the multiset.
84
85
```python { .api }
86
def difference(self, *others) -> BaseMultiset:
87
"""
88
Return a new multiset with elements from this multiset that are not in others.
89
Subtracts multiplicities of elements found in others.
90
91
Parameters:
92
- *others: Iterables or mappings to subtract
93
94
Returns:
95
New multiset with elements removed
96
"""
97
98
def __sub__(self, other) -> BaseMultiset:
99
"""Difference using - operator."""
100
101
def __rsub__(self, other) -> BaseMultiset:
102
"""Reverse difference using - operator."""
103
```
104
105
**Usage Examples:**
106
107
```python
108
ms1 = Multiset('aaab') # {'a': 3, 'b': 1}
109
ms2 = Multiset('ab') # {'a': 1, 'b': 1}
110
111
# Difference subtracts multiplicities
112
result = ms1.difference(ms2) # {'a': 2}
113
result = ms1 - ms2 # Same result using operator
114
```
115
116
### Symmetric Difference Operations
117
118
Symmetric difference returns elements that are in either multiset but not in both.
119
120
```python { .api }
121
def symmetric_difference(self, other) -> BaseMultiset:
122
"""
123
Return a new multiset with elements in either this multiset or other but not both.
124
Takes absolute difference of multiplicities.
125
126
Parameters:
127
- other: Iterable or mapping to compare with
128
129
Returns:
130
New multiset with symmetric difference
131
"""
132
133
def __xor__(self, other) -> BaseMultiset:
134
"""Symmetric difference using ^ operator."""
135
136
def __rxor__(self, other) -> BaseMultiset:
137
"""Reverse symmetric difference using ^ operator."""
138
```
139
140
**Usage Examples:**
141
142
```python
143
ms1 = Multiset('aaab') # {'a': 3, 'b': 1}
144
ms2 = Multiset('aabb') # {'a': 2, 'b': 2}
145
146
# Symmetric difference takes absolute difference
147
result = ms1.symmetric_difference(ms2) # {'a': 1, 'b': 1}
148
result = ms1 ^ ms2 # Same result using operator
149
```
150
151
### Combination Operations
152
153
Combination operations sum multiplicities of elements across all operands.
154
155
```python { .api }
156
def combine(self, *others) -> BaseMultiset:
157
"""
158
Return a new multiset combining this multiset with others.
159
Sums multiplicities of all elements.
160
161
Parameters:
162
- *others: Iterables or mappings to combine with
163
164
Returns:
165
New multiset with summed multiplicities
166
"""
167
168
def __add__(self, other) -> BaseMultiset:
169
"""Combination using + operator."""
170
171
def __radd__(self, other) -> BaseMultiset:
172
"""Reverse combination using + operator."""
173
```
174
175
**Usage Examples:**
176
177
```python
178
ms1 = Multiset('aab') # {'a': 2, 'b': 1}
179
ms2 = Multiset('abb') # {'a': 1, 'b': 2}
180
181
# Combination sums multiplicities
182
result = ms1.combine(ms2) # {'a': 3, 'b': 3}
183
result = ms1 + ms2 # Same result using operator
184
```
185
186
### Scaling Operations
187
188
Scaling operations multiply all multiplicities by a factor.
189
190
```python { .api }
191
def times(self, factor: int) -> BaseMultiset:
192
"""
193
Return a new multiset with all multiplicities scaled by factor.
194
195
Parameters:
196
- factor: Integer scaling factor (must be non-negative)
197
198
Returns:
199
New multiset with scaled multiplicities
200
201
Raises:
202
ValueError: If factor is negative
203
"""
204
205
def __mul__(self, factor: int) -> BaseMultiset:
206
"""Scaling using * operator."""
207
208
def __rmul__(self, factor: int) -> BaseMultiset:
209
"""Reverse scaling using * operator."""
210
```
211
212
**Usage Examples:**
213
214
```python
215
ms = Multiset('aab') # {'a': 2, 'b': 1}
216
217
# Scale multiplicities
218
result = ms.times(3) # {'a': 6, 'b': 3}
219
result = ms * 3 # Same result using operator
220
result = 2 * ms # {'a': 4, 'b': 2}
221
```
222
223
### Set Relationship Tests
224
225
Test relationships between multisets and other collections.
226
227
```python { .api }
228
def isdisjoint(self, other) -> bool:
229
"""
230
Return True if multiset has no elements in common with other.
231
232
Parameters:
233
- other: Iterable or mapping to compare with
234
235
Returns:
236
True if no common elements exist
237
"""
238
239
def issubset(self, other) -> bool:
240
"""
241
Return True if all elements in this multiset are contained in other
242
with sufficient multiplicities.
243
244
Parameters:
245
- other: Iterable or mapping to compare with
246
247
Returns:
248
True if this is a subset of other
249
"""
250
251
def issuperset(self, other) -> bool:
252
"""
253
Return True if all elements in other are contained in this multiset
254
with sufficient multiplicities.
255
256
Parameters:
257
- other: Iterable or mapping to compare with
258
259
Returns:
260
True if this is a superset of other
261
"""
262
263
def __le__(self, other) -> bool:
264
"""Subset test using <= operator."""
265
266
def __lt__(self, other) -> bool:
267
"""Proper subset test using < operator."""
268
269
def __ge__(self, other) -> bool:
270
"""Superset test using >= operator."""
271
272
def __gt__(self, other) -> bool:
273
"""Proper superset test using > operator."""
274
```
275
276
**Usage Examples:**
277
278
```python
279
ms1 = Multiset('ab') # {'a': 1, 'b': 1}
280
ms2 = Multiset('aabb') # {'a': 2, 'b': 2}
281
ms3 = Multiset('cd') # {'c': 1, 'd': 1}
282
283
# Relationship tests
284
ms1.isdisjoint(ms3) # True (no common elements)
285
ms1.issubset(ms2) # True (ms1 ⊆ ms2)
286
ms2.issuperset(ms1) # True (ms2 ⊇ ms1)
287
288
# Using operators
289
ms1 <= ms2 # True (subset)
290
ms1 < ms2 # True (proper subset)
291
ms2 >= ms1 # True (superset)
292
ms2 > ms1 # True (proper superset)
293
```
294
295
### Equality and Comparison
296
297
```python { .api }
298
def __eq__(self, other) -> bool:
299
"""
300
Return True if multisets have identical elements and multiplicities.
301
302
Parameters:
303
- other: Object to compare with
304
305
Returns:
306
True if multisets are equal
307
"""
308
309
def __ne__(self, other) -> bool:
310
"""Return True if multisets are not equal."""
311
```
312
313
**Usage Examples:**
314
315
```python
316
ms1 = Multiset('aab')
317
ms2 = Multiset(['a', 'a', 'b'])
318
ms3 = Multiset('abb')
319
320
ms1 == ms2 # True (same elements and multiplicities)
321
ms1 != ms3 # True (different multiplicities)
322
```