Python module for interacting with nested dicts as a single level dict with delimited keys.
npx @tessl/cli install tessl/pypi-flatdict@4.0.00
# FlatDict
1
2
Python module for interacting with nested dicts as a single level dict with delimited keys. FlatDict allows access to deeply nested values using composite keys (e.g., 'foo:bar:baz') while maintaining compatibility with standard dictionary operations through the MutableMapping interface.
3
4
## Package Information
5
6
- **Package Name**: flatdict
7
- **Language**: Python package
8
- **Installation**: `pip install flatdict`
9
10
## Core Imports
11
12
```python
13
import flatdict
14
```
15
16
For direct class access:
17
18
```python
19
from flatdict import FlatDict, FlatterDict
20
```
21
22
## Basic Usage
23
24
```python
25
import flatdict
26
27
# Create a FlatDict from nested dictionary
28
nested_data = {
29
'foo': {
30
'bar': 'baz',
31
'qux': 'corge'
32
},
33
'grault': {
34
'garply': 'waldo'
35
}
36
}
37
38
# FlatDict flattens nested structures
39
flat = flatdict.FlatDict(nested_data)
40
41
# Access using composite keys with delimiter (default ':')
42
print(flat['foo:bar']) # 'baz'
43
print(flat['foo:qux']) # 'corge'
44
print(flat['grault:garply']) # 'waldo'
45
46
# Also supports traditional dictionary access
47
print(flat['foo']['bar']) # 'baz'
48
49
# Iterate over flattened keys
50
for key in flat.keys():
51
print(f"{key}: {flat[key]}")
52
53
# Convert back to nested dictionary
54
nested = flat.as_dict()
55
```
56
57
## Architecture
58
59
FlatDict implements Python's `MutableMapping` abstract base class, providing a complete dictionary interface while internally managing nested data structures. The key innovation is the flattening mechanism that converts nested dictionaries into single-level dictionaries using delimited keys.
60
61
**Core Design:**
62
- **Flattening**: Nested dictionaries become single-level with composite keys (e.g., 'foo:bar:baz')
63
- **MutableMapping Interface**: Full compatibility with standard dictionary operations
64
- **Delimiter Customization**: Configurable key separator (default ':')
65
- **Type Preservation**: FlatterDict variant preserves original collection types (list, tuple, set)
66
67
This approach allows intuitive access to deeply nested data while maintaining the familiar dictionary API that Python developers expect.
68
69
## Capabilities
70
71
### FlatDict Class
72
73
Main dictionary class that flattens nested dictionaries into single-level dictionaries with delimited keys. Implements the MutableMapping interface for full dictionary compatibility.
74
75
```python { .api }
76
class FlatDict:
77
def __init__(self, value=None, delimiter=':', dict_class=dict):
78
"""
79
Initialize FlatDict.
80
81
Parameters:
82
- value: dict or None, initial nested dictionary to flatten
83
- delimiter: str, character to use for key separation (default ':')
84
- dict_class: type, dictionary class to use internally (default dict)
85
"""
86
87
def __contains__(self, key):
88
"""Check if key exists, supporting both delimited and non-delimited keys."""
89
90
def __delitem__(self, key):
91
"""Delete item by key, automatically handling nested children."""
92
93
def __eq__(self, other):
94
"""Check equality against dict or FlatDict."""
95
96
def __ne__(self, other):
97
"""Check inequality against dict or FlatDict."""
98
99
def __getitem__(self, key):
100
"""Get item by key, supporting delimited key access."""
101
102
def __iter__(self):
103
"""Iterate over flattened keys."""
104
105
def __len__(self):
106
"""Return number of flattened items."""
107
108
def __setitem__(self, key, value):
109
"""Set item by key, supporting delimited key assignment."""
110
111
def __str__(self):
112
"""String representation of flattened dictionary."""
113
114
def __repr__(self):
115
"""Detailed string representation."""
116
117
def __reduce__(self):
118
"""
119
Return state information for pickling.
120
121
Returns:
122
tuple: State information for pickle reconstruction
123
"""
124
125
def as_dict(self):
126
"""
127
Convert FlatDict back to nested dictionary.
128
129
Returns:
130
dict: Nested dictionary representation
131
"""
132
133
def clear(self):
134
"""Remove all items from the flat dictionary."""
135
136
def copy(self):
137
"""
138
Return shallow copy of the flat dictionary.
139
140
Returns:
141
FlatDict: Copy with same delimiter
142
"""
143
144
def get(self, key, d=None):
145
"""
146
Get item with default value.
147
148
Parameters:
149
- key: Key to lookup
150
- d: Default value if key not found
151
152
Returns:
153
Value at key or default
154
"""
155
156
def items(self):
157
"""
158
Return list of (key, value) pairs.
159
160
Returns:
161
list: Flattened key-value pairs
162
"""
163
164
def iteritems(self):
165
"""Iterator over (key, value) pairs."""
166
167
def iterkeys(self):
168
"""Iterator over flattened keys."""
169
170
def itervalues(self):
171
"""Iterator over values."""
172
173
def keys(self):
174
"""
175
Return list of flattened keys.
176
177
Returns:
178
list: All flattened keys with delimiters
179
"""
180
181
def pop(self, key, default=None):
182
"""
183
Remove and return item.
184
185
Parameters:
186
- key: Key to remove
187
- default: Value to return if key not found (optional)
188
189
Returns:
190
Value that was removed or default
191
192
Raises:
193
KeyError: If key not found and no default provided
194
"""
195
196
def setdefault(self, key, default):
197
"""
198
Get item or set and return default.
199
200
Parameters:
201
- key: Key to check/set
202
- default: Value to set if key doesn't exist
203
204
Returns:
205
Value at key or default that was set
206
"""
207
208
def set_delimiter(self, delimiter):
209
"""
210
Change the delimiter character.
211
212
Parameters:
213
- delimiter: str, new delimiter character
214
215
Raises:
216
ValueError: If delimiter conflicts with existing keys
217
"""
218
219
def update(self, other=None, **kwargs):
220
"""
221
Update with key/value pairs from other dict or kwargs.
222
223
Parameters:
224
- other: dict-like object or iterable of key/value pairs
225
- **kwargs: Additional key/value pairs
226
"""
227
228
def values(self):
229
"""
230
Return list of values.
231
232
Returns:
233
list: All values in the flattened dictionary
234
"""
235
```
236
237
### FlatterDict Class
238
239
Extended version of FlatDict that also handles lists, tuples, and sets by converting them to dictionary structures using enumeration. Maintains original type information for reconstruction.
240
241
```python { .api }
242
class FlatterDict(FlatDict):
243
def __init__(self, value=None, delimiter=':', dict_class=dict):
244
"""
245
Initialize FlatterDict with array coercion.
246
247
Parameters:
248
- value: dict, list, tuple, set, or None - initial data structure
249
- delimiter: str, character for key separation (default ':')
250
- dict_class: type, dictionary class to use internally (default dict)
251
252
Attributes:
253
- original_type: type, stores the original type of the input value
254
255
Class Constants:
256
- _COERCE: tuple, types that get coerced to FlatterDict (list, tuple, set, dict, FlatDict)
257
- _ARRAYS: tuple, array types that get special handling (list, set, tuple)
258
"""
259
260
def __setitem__(self, key, value):
261
"""Enhanced setitem that handles arrays (list, tuple, set)."""
262
263
def as_dict(self):
264
"""
265
Convert FlatterDict back to nested structure preserving original types.
266
267
Returns:
268
dict: Nested structure with original array types restored
269
"""
270
```
271
272
### Module Constants
273
274
```python { .api }
275
__version__: str # Package version string
276
277
NO_DEFAULT: object # Sentinel object for internal use
278
```
279
280
### Class Constants
281
282
```python { .api }
283
# FlatDict class constants
284
FlatDict._COERCE = dict # Types that get coerced to FlatDict
285
286
# FlatterDict class constants
287
FlatterDict._COERCE = (list, tuple, set, dict, FlatDict) # Types coerced to FlatterDict
288
FlatterDict._ARRAYS = (list, set, tuple) # Array types with special handling
289
```
290
291
## Error Handling
292
293
The flatdict module raises standard Python exceptions:
294
295
- **KeyError**: Raised when accessing non-existent keys through `__getitem__`, `__delitem__`, or `pop()` without default
296
- **TypeError**: Raised for invalid assignments or when trying to assign to incompatible nested structures
297
- **ValueError**: Raised by `set_delimiter()` when the new delimiter conflicts with existing keys
298
- **RuntimeError**: May be raised during iteration if the dictionary is modified during iteration
299
300
## Advanced Usage
301
302
### Custom Delimiters
303
304
```python
305
# Use different delimiter
306
flat = flatdict.FlatDict({'a': {'b': 'c'}}, delimiter='.')
307
print(flat['a.b']) # 'c'
308
309
# Change delimiter after creation
310
flat.set_delimiter('/')
311
print(flat['a/b']) # 'c'
312
```
313
314
### Working with Arrays (FlatterDict)
315
316
```python
317
# FlatterDict handles lists, tuples, and sets
318
data = {
319
'items': ['a', 'b', 'c'],
320
'coords': (1, 2, 3),
321
'tags': {'red', 'blue', 'green'}
322
}
323
324
flatter = flatdict.FlatterDict(data)
325
326
# Access array elements by index
327
print(flatter['items:0']) # 'a'
328
print(flatter['coords:1']) # 2
329
330
# Convert back preserving original types
331
restored = flatter.as_dict()
332
print(type(restored['items'])) # <class 'list'>
333
print(type(restored['coords'])) # <class 'tuple'>
334
print(type(restored['tags'])) # <class 'set'>
335
```
336
337
### Dictionary Operations
338
339
```python
340
flat = flatdict.FlatDict({'a': {'b': 1, 'c': 2}})
341
342
# Standard dictionary operations work
343
len(flat) # 2
344
'a:b' in flat # True
345
list(flat) # ['a:b', 'a:c']
346
347
# Update with nested data
348
flat.update({'d': {'e': 3}})
349
print(flat['d:e']) # 3
350
351
# Copy preserves delimiter
352
flat2 = flat.copy()
353
```