or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

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

setlists.mddocs/

0

# Setlists and Ordered Sets

1

2

Setlists are ordered collections of unique elements that combine list-like indexing with set-like uniqueness constraints. They maintain insertion order while enforcing element uniqueness, providing efficient index-based access and set operations.

3

4

## Capabilities

5

6

### Setlist Construction

7

8

Create ordered sets from iterables with automatic duplicate removal.

9

10

```python { .api }

11

class SetList:

12

def __init__(self, iterable=None, raise_on_duplicate=False):

13

"""Create a setlist from an iterable.

14

15

Args:

16

iterable: Values to initialize the setlist with

17

raise_on_duplicate: If True, raise ValueError on duplicate values

18

"""

19

20

def setlist(iterable=None, raise_on_duplicate=False):

21

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

22

23

def frozensetlist(iterable=None, raise_on_duplicate=False):

24

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

25

```

26

27

Usage examples:

28

```python

29

from collections_extended import setlist, frozensetlist

30

31

# Create from string - duplicates removed, order preserved

32

sl = setlist('abracadabra')

33

print(sl) # setlist(('a', 'b', 'r', 'c', 'd'))

34

35

# Raise error on duplicates

36

try:

37

sl = setlist('hello', raise_on_duplicate=True)

38

except ValueError:

39

print("Duplicate 'l' found")

40

41

# Create immutable setlist

42

fsl = frozensetlist([1, 2, 3, 2, 1])

43

print(len(fsl)) # 3

44

```

45

46

### Sequence Operations

47

48

Access and query elements using list-like indexing and sequence operations.

49

50

```python { .api }

51

def __getitem__(self, index):

52

"""Get element at index or slice.

53

54

Args:

55

index: int or slice object

56

57

Returns:

58

Element at index or new setlist for slices

59

"""

60

61

def index(self, value, start=0, end=None):

62

"""Return index of value between start and end.

63

64

Args:

65

value: Element to find

66

start: Start index for search

67

end: End index for search

68

69

Returns:

70

int: Index of the element

71

72

Raises:

73

ValueError: If value not found or outside start-end range

74

"""

75

76

def count(self, value):

77

"""Return count of value (always 0 or 1 for setlists).

78

79

Args:

80

value: Element to count

81

82

Returns:

83

int: 1 if value in setlist, 0 otherwise

84

"""

85

86

def sub_index(self, sub, start=0, end=None):

87

"""Return index of a subsequence.

88

89

Args:

90

sub: Sequence to search for

91

start: Start index for search

92

end: End index for search

93

94

Returns:

95

int: Index of first element of subsequence

96

97

Raises:

98

ValueError: If subsequence not found

99

"""

100

```

101

102

Usage examples:

103

```python

104

sl = setlist('abcde')

105

print(sl[2]) # 'c'

106

print(sl[1:4]) # setlist(('b', 'c', 'd'))

107

print(sl.index('d')) # 3

108

print(sl.count('c')) # 1

109

print(sl.sub_index(['b', 'c'])) # 1

110

```

111

112

### Mutable Setlist Operations

113

114

Modify setlist contents while maintaining uniqueness constraints.

115

116

```python { .api }

117

def append(self, value):

118

"""Append value to the end.

119

120

Args:

121

value: Value to append

122

123

Raises:

124

ValueError: If value already in setlist

125

"""

126

127

def insert(self, index, value):

128

"""Insert value at index.

129

130

Args:

131

index: Position to insert at

132

value: Value to insert

133

134

Raises:

135

ValueError: If value already in setlist

136

"""

137

138

def extend(self, values):

139

"""Append all values to the end.

140

141

Args:

142

values: Iterable of values to append

143

144

Raises:

145

ValueError: If any value already present or duplicates in values

146

"""

147

148

def remove(self, value):

149

"""Remove value from setlist.

150

151

Args:

152

value: Element to remove

153

154

Raises:

155

ValueError: If value not present

156

"""

157

158

def pop(self, index=-1):

159

"""Remove and return item at index.

160

161

Args:

162

index: Index to pop (default: last item)

163

164

Returns:

165

Any: The removed element

166

"""

167

168

def clear(self):

169

"""Remove all elements from setlist."""

170

171

def reverse(self):

172

"""Reverse the setlist in-place."""

173

174

def sort(self, *args, **kwargs):

175

"""Sort the setlist in-place."""

176

177

def swap(self, i, j):

178

"""Swap elements at indices i and j."""

179

```

180

181

Usage examples:

182

```python

183

sl = setlist(['a', 'b', 'c'])

184

sl.append('d') # setlist(['a', 'b', 'c', 'd'])

185

sl.insert(1, 'x') # setlist(['a', 'x', 'b', 'c', 'd'])

186

sl.extend(['e', 'f']) # setlist(['a', 'x', 'b', 'c', 'd', 'e', 'f'])

187

188

item = sl.pop() # 'f', setlist now ['a', 'x', 'b', 'c', 'd', 'e']

189

sl.remove('x') # setlist(['a', 'b', 'c', 'd', 'e'])

190

sl.reverse() # setlist(['e', 'd', 'c', 'b', 'a'])

191

```

192

193

### Set Operations

194

195

Mathematical set operations that preserve order based on the left operand.

196

197

```python { .api }

198

def union(self, other):

199

"""Return union of setlists (all elements from both)."""

200

201

def intersection(self, other):

202

"""Return intersection of setlists (common elements)."""

203

204

def difference(self, other):

205

"""Return difference of setlists (elements in self but not other)."""

206

207

def symmetric_difference(self, other):

208

"""Return symmetric difference (elements in either but not both)."""

209

210

def __add__(self, other):

211

"""Concatenate setlists (other elements appended, duplicates raise error)."""

212

213

def __sub__(self, other):

214

"""Return difference of setlists."""

215

216

def __and__(self, other):

217

"""Return intersection of setlists."""

218

219

def __or__(self, other):

220

"""Return union of setlists."""

221

222

def __xor__(self, other):

223

"""Return symmetric difference of setlists."""

224

225

def issubset(self, other):

226

"""Check if all elements are in other."""

227

228

def issuperset(self, other):

229

"""Check if all elements of other are in self."""

230

```

231

232

Usage examples:

233

```python

234

sl1 = setlist('abc')

235

sl2 = setlist('bcd')

236

237

print(sl1 | sl2) # setlist(['a', 'b', 'c', 'd']) (union)

238

print(sl1 & sl2) # setlist(['b', 'c']) (intersection)

239

print(sl1 - sl2) # setlist(['a']) (difference)

240

print(sl1 ^ sl2) # setlist(['a', 'd']) (symmetric difference)

241

242

print(setlist('ab').issubset(sl1)) # True

243

```

244

245

### Set-like Mutable Operations

246

247

Mutable set operations that modify the setlist in-place.

248

249

```python { .api }

250

def add(self, item):

251

"""Add item if not already present (like set.add)."""

252

253

def update(self, values):

254

"""Add all values, ignoring duplicates (like set.update)."""

255

256

def discard(self, value):

257

"""Remove value if present, silent if missing (like set.discard)."""

258

259

def discard_all(self, elems_to_delete):

260

"""Remove all elements in elems_to_delete, ignoring missing."""

261

262

def remove_all(self, elems_to_delete):

263

"""Remove all elements in elems_to_delete.

264

265

Raises:

266

ValueError: If any element not present or duplicates in elems_to_delete

267

"""

268

269

def difference_update(self, other):

270

"""Remove all elements in other from self."""

271

272

def intersection_update(self, other):

273

"""Keep only elements also in other."""

274

275

def symmetric_difference_update(self, other):

276

"""Update to symmetric difference with other."""

277

```

278

279

Usage examples:

280

```python

281

sl = setlist('abc')

282

sl.add('d') # setlist(['a', 'b', 'c', 'd'])

283

sl.add('b') # No change - 'b' already present

284

sl.update('efg') # setlist(['a', 'b', 'c', 'd', 'e', 'f', 'g'])

285

sl.discard('x') # No error - 'x' not present

286

sl.discard_all('aei') # Removes 'a' and 'e', ignores 'i'

287

```

288

289

### Sequence-like Mutable Operations

290

291

Additional list-like operations for fine-grained control.

292

293

```python { .api }

294

def __setitem__(self, index, value):

295

"""Set element at index to value.

296

297

Args:

298

index: int or slice

299

value: New value or sequence of values

300

301

Raises:

302

ValueError: If value already exists elsewhere in setlist

303

"""

304

305

def __delitem__(self, index):

306

"""Delete element at index or slice."""

307

308

def shuffle(self, random=None):

309

"""Shuffle elements in-place.

310

311

Args:

312

random: Random function (default: random.random)

313

"""

314

```

315

316

Usage examples:

317

```python

318

sl = setlist(['a', 'b', 'c', 'd'])

319

sl[1] = 'x' # setlist(['a', 'x', 'c', 'd'])

320

del sl[0] # setlist(['x', 'c', 'd'])

321

sl.shuffle() # Random order, e.g., setlist(['d', 'x', 'c'])

322

```

323

324

### Immutable Setlists

325

326

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

327

328

```python { .api }

329

class frozensetlist(SetList, Hashable):

330

def __hash__(self):

331

"""Return hash value for the frozensetlist."""

332

```

333

334

Usage examples:

335

```python

336

from collections_extended import frozensetlist

337

338

# Immutable setlists can be dict keys

339

fsl1 = frozensetlist('abc')

340

fsl2 = frozensetlist('def')

341

mapping = {fsl1: 'first', fsl2: 'second'}

342

343

# Or in sets

344

setlist_set = {frozensetlist('hello'), frozensetlist('world')}

345

```

346

347

### Copy and Comparison

348

349

Create copies and compare setlists efficiently.

350

351

```python { .api }

352

def copy(self):

353

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

354

355

def __eq__(self, other):

356

"""Check equality with another setlist (order matters)."""

357

358

def __ne__(self, other):

359

"""Check inequality with another setlist."""

360

```