or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

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

indexed-dicts.mddocs/

0

# Indexed Dictionaries

1

2

IndexedDict provides ordered mappings with both key-based and index-based access. It maintains insertion order while providing efficient positional access, making it ideal for scenarios requiring both dictionary semantics and list-like indexing.

3

4

## Capabilities

5

6

### IndexedDict Construction

7

8

Create ordered dictionaries from various input formats with both key and index access.

9

10

```python { .api }

11

class IndexedDict:

12

def __init__(self, iterable=None, **kwargs):

13

"""Create an IndexedDict.

14

15

Args:

16

iterable: Mapping or iterable of (key, value) pairs

17

**kwargs: Additional key-value pairs

18

"""

19

```

20

21

Usage examples:

22

```python

23

from collections_extended import IndexedDict

24

25

# Create empty

26

idict = IndexedDict()

27

28

# Create from dictionary

29

idict = IndexedDict({'a': 1, 'b': 2, 'c': 3})

30

31

# Create from iterable of pairs

32

idict = IndexedDict([('x', 10), ('y', 20), ('z', 30)])

33

34

# Create with keyword arguments

35

idict = IndexedDict(name='Alice', age=30, city='NYC')

36

37

# Mix approaches

38

idict = IndexedDict({'a': 1}, b=2, c=3)

39

```

40

41

### Dual Access Patterns

42

43

Access elements by either key or index position efficiently.

44

45

```python { .api }

46

def get(self, key=NOT_SET, index=NOT_SET, default=NOT_SET):

47

"""Get value by key or index.

48

49

Args:

50

key: Key to look up (mutually exclusive with index)

51

index: Index to look up (mutually exclusive with key)

52

default: Value to return if not found (None if not specified)

53

54

Returns:

55

Any: Value at key/index or default

56

57

Raises:

58

TypeError: If both or neither key and index specified

59

"""

60

61

def __getitem__(self, key):

62

"""Get value by key.

63

64

Args:

65

key: Key to look up

66

67

Returns:

68

Any: Value associated with key

69

70

Raises:

71

KeyError: If key not found

72

"""

73

74

def index(self, key):

75

"""Get index of a key.

76

77

Args:

78

key: Key to find index of

79

80

Returns:

81

int: Index position of key

82

83

Raises:

84

KeyError: If key not found

85

"""

86

87

def key(self, index):

88

"""Get key at a specific index.

89

90

Args:

91

index: Index position

92

93

Returns:

94

Any: Key at the specified index

95

96

Raises:

97

IndexError: If index out of bounds

98

"""

99

```

100

101

Usage examples:

102

```python

103

idict = IndexedDict([('a', 1), ('b', 2), ('c', 3)])

104

105

# Access by key

106

print(idict['b']) # 2

107

print(idict.get(key='b')) # 2

108

109

# Access by index

110

print(idict.get(index=1)) # 2 (value at index 1)

111

print(idict.key(1)) # 'b' (key at index 1)

112

113

# Get index of key

114

print(idict.index('c')) # 2

115

116

# Safe access with defaults

117

print(idict.get(key='missing', default='not found')) # 'not found'

118

print(idict.get(index=10, default='out of bounds')) # 'out of bounds'

119

```

120

121

### Standard Mapping Operations

122

123

All standard dictionary operations with order preservation.

124

125

```python { .api }

126

def __setitem__(self, key, value):

127

"""Set key to value, preserving order for existing keys.

128

129

Args:

130

key: Key to set

131

value: Value to associate with key

132

"""

133

134

def __delitem__(self, key):

135

"""Delete key and its value.

136

137

Args:

138

key: Key to delete

139

140

Raises:

141

KeyError: If key not found

142

"""

143

144

def __contains__(self, key):

145

"""Check if key exists.

146

147

Args:

148

key: Key to check

149

150

Returns:

151

bool: True if key exists

152

"""

153

154

def __len__(self):

155

"""Return number of key-value pairs.

156

157

Returns:

158

int: Number of items

159

"""

160

161

def __iter__(self):

162

"""Iterate over keys in insertion order."""

163

164

def keys(self):

165

"""Return view of keys in order."""

166

167

def values(self):

168

"""Return view of values in order."""

169

170

def items(self):

171

"""Return view of (key, value) pairs in order."""

172

```

173

174

Usage examples:

175

```python

176

idict = IndexedDict()

177

178

# Add items - order preserved

179

idict['first'] = 1

180

idict['second'] = 2

181

idict['third'] = 3

182

183

# Update existing key - position unchanged

184

idict['second'] = 'two'

185

186

print(list(idict.keys())) # ['first', 'second', 'third']

187

print(list(idict.values())) # [1, 'two', 3]

188

189

# Standard operations

190

print('second' in idict) # True

191

print(len(idict)) # 3

192

193

del idict['first']

194

print(list(idict.keys())) # ['second', 'third']

195

```

196

197

### Positional Removal Operations

198

199

Remove elements by key, index, or from ends with flexible options.

200

201

```python { .api }

202

def pop(self, key=NOT_SET, index=NOT_SET, default=NOT_SET):

203

"""Remove and return value by key or index.

204

205

Args:

206

key: Key to pop (mutually exclusive with index)

207

index: Index to pop (mutually exclusive with key, -1 for last)

208

default: Value to return if key/index not found

209

210

Returns:

211

Any: Removed value or default

212

213

Raises:

214

KeyError: If key not found and no default

215

IndexError: If index out of bounds and no default

216

TypeError: If both or neither key and index specified

217

"""

218

219

def popitem(self, last=NOT_SET, *, key=NOT_SET, index=NOT_SET):

220

"""Remove and return (key, value) pair.

221

222

Args:

223

last: If True pop last item, if False pop first (for OrderedDict compatibility)

224

key: Key to pop (keyword only)

225

index: Index to pop (keyword only)

226

227

Returns:

228

tuple: (key, value) pair that was removed

229

230

Raises:

231

KeyError: If dict empty or key not found

232

IndexError: If index out of bounds

233

"""

234

235

def fast_pop(self, key=NOT_SET, index=NOT_SET):

236

"""Pop item quickly by swapping with last item.

237

238

Changes order but runs in O(1) instead of O(n).

239

240

Args:

241

key: Key to pop (mutually exclusive with index)

242

index: Index to pop (mutually exclusive with key)

243

244

Returns:

245

tuple: (popped_value, moved_index, moved_key, moved_value)

246

"""

247

```

248

249

Usage examples:

250

```python

251

idict = IndexedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])

252

253

# Pop by key

254

value = idict.pop(key='b') # 2, dict now [('a', 1), ('c', 3), ('d', 4)]

255

256

# Pop by index

257

value = idict.pop(index=1) # 3, dict now [('a', 1), ('d', 4)]

258

259

# Pop last item (default)

260

value = idict.pop() # 4, dict now [('a', 1)]

261

262

# Pop with default

263

value = idict.pop(key='missing', default='not found') # 'not found'

264

265

# Pop item pairs

266

idict = IndexedDict([('x', 10), ('y', 20), ('z', 30)])

267

key, value = idict.popitem() # ('z', 30) - last item

268

key, value = idict.popitem(last=False) # ('x', 10) - first item

269

270

# Fast pop for better performance

271

idict = IndexedDict([('a', 1), ('b', 2), ('c', 3)])

272

popped_val, moved_idx, moved_key, moved_val = idict.fast_pop(key='a')

273

# Result: popped_val=1, moved_idx=0, moved_key='c', moved_val=3

274

# Dict order changed: [('c', 3), ('b', 2)]

275

```

276

277

### Order Manipulation

278

279

Reorder elements within the indexed dictionary.

280

281

```python { .api }

282

def move_to_end(self, key=NOT_SET, index=NOT_SET, last=True):

283

"""Move existing element to end or beginning.

284

285

Args:

286

key: Key to move (mutually exclusive with index)

287

index: Index to move (mutually exclusive with key)

288

last: If True move to end, if False move to beginning

289

290

Raises:

291

KeyError: If key not found

292

IndexError: If index out of bounds

293

"""

294

```

295

296

Usage examples:

297

```python

298

idict = IndexedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])

299

300

# Move to end

301

idict.move_to_end(key='b') # [('a', 1), ('c', 3), ('d', 4), ('b', 2)]

302

303

# Move to beginning

304

idict.move_to_end(key='d', last=False) # [('d', 4), ('a', 1), ('c', 3), ('b', 2)]

305

306

# Move by index

307

idict.move_to_end(index=1) # [('d', 4), ('c', 3), ('b', 2), ('a', 1)]

308

```

309

310

### Utility Operations

311

312

Copy, clear, and manage IndexedDict state.

313

314

```python { .api }

315

def copy(self):

316

"""Return shallow copy of the IndexedDict.

317

318

Returns:

319

IndexedDict: New IndexedDict with same items

320

"""

321

322

def clear(self):

323

"""Remove all items from the IndexedDict."""

324

325

def update(self, other=None, **kwargs):

326

"""Update with key-value pairs from other or kwargs.

327

328

Args:

329

other: Mapping or iterable of pairs to update from

330

**kwargs: Additional key-value pairs

331

"""

332

```

333

334

Usage examples:

335

```python

336

original = IndexedDict([('a', 1), ('b', 2)])

337

338

# Copy

339

copy_dict = original.copy()

340

copy_dict['c'] = 3

341

print(len(original)) # 2 - original unchanged

342

print(len(copy_dict)) # 3

343

344

# Update

345

original.update({'c': 3, 'd': 4})

346

original.update(e=5, f=6)

347

print(len(original)) # 6

348

349

# Clear

350

original.clear()

351

print(len(original)) # 0

352

```

353

354

### String Representations

355

356

Formatted output for debugging and display.

357

358

```python { .api }

359

def __repr__(self):

360

"""Detailed representation showing internal structure."""

361

362

def __str__(self):

363

"""String representation as ordered dictionary."""

364

```

365

366

Usage examples:

367

```python

368

idict = IndexedDict([('name', 'Alice'), ('age', 30), ('city', 'NYC')])

369

370

print(repr(idict))

371

# IndexedDict([('name', 'Alice'), ('age', 30), ('city', 'NYC')])

372

373

print(str(idict))

374

# IndexedDict({'name': 'Alice', 'age': 30, 'city': 'NYC'})

375

```

376

377

### Advanced Usage Patterns

378

379

Common patterns for effective IndexedDict usage.

380

381

```python

382

# Building ordered mappings

383

config = IndexedDict()

384

config['database_url'] = 'postgresql://...'

385

config['redis_url'] = 'redis://...'

386

config['secret_key'] = 'abc123'

387

388

# Access by position for ordered processing

389

for i in range(len(config)):

390

key = config.key(i)

391

value = config[key]

392

print(f"Setting {i+1}: {key} = {value}")

393

394

# Reorder based on priority

395

priority_keys = ['secret_key', 'database_url', 'redis_url']

396

ordered_config = IndexedDict()

397

for key in priority_keys:

398

if key in config:

399

ordered_config[key] = config[key]

400

401

# Index-based slicing simulation

402

def slice_indexed_dict(idict, start, stop):

403

result = IndexedDict()

404

for i in range(start, min(stop, len(idict))):

405

key = idict.key(i)

406

result[key] = idict[key]

407

return result

408

409

partial = slice_indexed_dict(config, 1, 3) # Items at indices 1-2

410

411

# LRU-like behavior with move_to_end

412

cache = IndexedDict()

413

def access_item(key):

414

if key in cache:

415

cache.move_to_end(key) # Move to end on access

416

return cache[key]

417

return None

418

419

# Batch operations maintaining order

420

def batch_update_preserve_order(idict, updates):

421

# Update existing keys in place, append new keys at end

422

new_keys = []

423

for key, value in updates.items():

424

if key in idict:

425

idict[key] = value

426

else:

427

new_keys.append((key, value))

428

429

# Add new keys at end

430

for key, value in new_keys:

431

idict[key] = value

432

```

433

434

### Error Handling and Edge Cases

435

436

Understanding IndexedDict behavior in various scenarios.

437

438

```python

439

# Key vs index parameter validation

440

idict = IndexedDict([('a', 1), ('b', 2)])

441

442

try:

443

# Must specify exactly one of key or index

444

idict.get() # TypeError - neither specified

445

except TypeError as e:

446

print(f"Error: {e}")

447

448

try:

449

idict.get(key='a', index=0) # TypeError - both specified

450

except TypeError as e:

451

print(f"Error: {e}")

452

453

# Handling missing keys/indices gracefully

454

value = idict.get(key='missing', default='not found')

455

value = idict.get(index=10, default='out of bounds')

456

457

# Empty dict behavior

458

empty = IndexedDict()

459

try:

460

empty.popitem() # KeyError

461

except KeyError:

462

print("Cannot pop from empty IndexedDict")

463

464

# Negative index support

465

idict = IndexedDict([('a', 1), ('b', 2), ('c', 3)])

466

last_value = idict.get(index=-1) # 3

467

second_last = idict.get(index=-2) # 2

468

```