or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bags.mdbijections.mdindex.mdindexed-dicts.mdrange-maps.mdsetlists.md

bags.mddocs/

0

# Bags and Multisets

1

2

Bags (also known as multisets) are collections that track element counts, allowing duplicates while maintaining count information. They support mathematical set operations with multiplicity, statistical operations on collections, and efficient counting operations.

3

4

## Capabilities

5

6

### Bag Construction

7

8

Create bags from iterables with automatic element counting.

9

10

```python { .api }

11

class Bag:

12

def __init__(self, iterable=None):

13

"""Create a new bag.

14

15

Args:

16

iterable: Iterable to populate the bag from. Each element will be

17

added however many times it appears.

18

"""

19

20

def bag(iterable=None):

21

"""Create a mutable bag from an iterable."""

22

23

def frozenbag(iterable=None):

24

"""Create an immutable, hashable bag from an iterable."""

25

```

26

27

Usage examples:

28

```python

29

from collections_extended import bag, frozenbag

30

31

# Create from string - counts each character

32

b = bag('abracadabra')

33

print(b) # bag(('a', 'a', 'a', 'a', 'a', 'b', 'b', 'r', 'r', 'c', 'd'))

34

35

# Create from list

36

b = bag([1, 2, 2, 3, 3, 3])

37

print(b.count(3)) # 3

38

39

# Create immutable bag

40

fb = frozenbag('hello')

41

print(fb.count('l')) # 2

42

```

43

44

### Element Counting and Access

45

46

Query element counts and access unique elements efficiently.

47

48

```python { .api }

49

def count(self, value):

50

"""Return the number of times value appears in this bag.

51

52

Args:

53

value: The element to count

54

55

Returns:

56

int: Count of value in the bag (0 if not present)

57

"""

58

59

def num_unique_elements(self):

60

"""Return the number of unique elements.

61

62

Returns:

63

int: Number of distinct elements

64

"""

65

66

def unique_elements(self):

67

"""Return a view of unique elements in this bag.

68

69

Returns:

70

UniqueElementsView: View of unique elements

71

"""

72

73

def counts(self):

74

"""Return a view of (element, count) pairs.

75

76

Returns:

77

CountsView: View of element-count pairs

78

"""

79

```

80

81

### Mutable Bag Operations

82

83

Modify bag contents by adding, removing, and updating elements.

84

85

```python { .api }

86

def add(self, elem):

87

"""Add elem to the bag (increment its count by 1)."""

88

89

def remove(self, elem):

90

"""Remove one occurrence of elem from the bag.

91

92

Raises:

93

ValueError: If elem is not in the bag

94

"""

95

96

def discard(self, elem):

97

"""Remove one occurrence of elem from the bag if present."""

98

99

def pop(self):

100

"""Remove and return an arbitrary element from the bag.

101

102

Returns:

103

Any: An element from the bag

104

105

Raises:

106

KeyError: If bag is empty

107

"""

108

109

def clear(self):

110

"""Remove all elements from the bag."""

111

112

def discard_all(self, other):

113

"""Remove all elements from other, ignoring missing elements."""

114

115

def remove_all(self, other):

116

"""Remove all elements from other.

117

118

Raises:

119

ValueError: If any element in other has higher count than in self

120

"""

121

```

122

123

### Set Operations with Multiplicity

124

125

Mathematical set operations that preserve element counts.

126

127

```python { .api }

128

def __add__(self, other):

129

"""Return new bag with elements from both bags (counts added)."""

130

131

def __sub__(self, other):

132

"""Return new bag with elements of other removed from self."""

133

134

def __and__(self, other):

135

"""Return intersection (minimum counts for each element)."""

136

137

def __or__(self, other):

138

"""Return union (maximum counts for each element)."""

139

140

def __xor__(self, other):

141

"""Return symmetric difference (absolute difference of counts)."""

142

143

def issubset(self, other):

144

"""Check if every element in self has count <= in other."""

145

146

def issuperset(self, other):

147

"""Check if every element in self has count >= in other."""

148

149

def isdisjoint(self, other):

150

"""Return True if bags have no elements in common."""

151

```

152

153

Usage examples:

154

```python

155

a = bag('aab') # a:2, b:1

156

b = bag('abc') # a:1, b:1, c:1

157

158

print(a + b) # bag: a:3, b:2, c:1

159

print(a - b) # bag: a:1 (2-1)

160

print(a & b) # bag: a:1, b:1 (minimums)

161

print(a | b) # bag: a:2, b:1, c:1 (maximums)

162

print(a.issubset(bag('aaabbc'))) # True

163

```

164

165

### Statistical and Advanced Operations

166

167

Advanced operations for analysis and manipulation.

168

169

```python { .api }

170

def product(self, other, operator=None):

171

"""Cartesian product of two bags.

172

173

Args:

174

other: Another iterable

175

operator: Optional function to combine elements instead of creating tuples

176

177

Returns:

178

bag: New bag with product elements

179

"""

180

181

@classmethod

182

def from_mapping(cls, mapping):

183

"""Create a bag from a dict of element->count.

184

185

Args:

186

mapping: Dict mapping elements to their counts

187

188

Raises:

189

ValueError: If any count is negative

190

"""

191

192

def copy(self):

193

"""Return a shallow copy of the bag."""

194

```

195

196

### Immutable Bags

197

198

Create hashable, immutable versions of bags for use as dictionary keys or set elements.

199

200

```python { .api }

201

class frozenbag(Bag, Hashable):

202

def __hash__(self):

203

"""Return hash value for the frozenbag."""

204

```

205

206

Usage examples:

207

```python

208

from collections_extended import frozenbag

209

210

# Immutable bags can be used as dict keys

211

fb1 = frozenbag('abc')

212

fb2 = frozenbag('def')

213

mapping = {fb1: 'first', fb2: 'second'}

214

215

# Or in sets

216

bag_set = {frozenbag('hello'), frozenbag('world')}

217

```

218

219

### View Classes

220

221

Specialized views providing different perspectives on bag contents.

222

223

```python { .api }

224

class UniqueElementsView:

225

"""A view of unique elements in a bag."""

226

def __iter__(self): ...

227

def __contains__(self, elem): ...

228

def __len__(self): ...

229

230

class CountsView:

231

"""A view of (element, count) pairs in a bag."""

232

def __iter__(self): ...

233

def __contains__(self, item): ...

234

def __len__(self): ...

235

```

236

237

Usage examples:

238

```python

239

b = bag('hello world')

240

241

# Iterate over unique elements

242

for elem in b.unique_elements():

243

print(f"{elem}: {b.count(elem)}")

244

245

# Iterate over (element, count) pairs

246

for elem, count in b.counts():

247

print(f"{elem} appears {count} times")

248

249

# Check if specific count exists

250

print(('l', 3) in b.counts()) # True

251

```