Skip to content

Commit 63e8a96

Browse files
committed
release v0.1.2
1 parent 3492a71 commit 63e8a96

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

pkg/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespaces = true
1717
# ----------------------------------------- Project Metadata -------------------------------------
1818
#
1919
[project]
20-
version = "0.1.1"
20+
version = "0.1.2"
2121
name = "PySerials"
2222
dependencies = [
2323
"jsonschema >= 4.21.0, < 5",

pkg/src/pyserials/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
from pyserials import exception, update, validate, read, write, format, compare
44
from pyserials.nested_dict import NestedDict
55
from pyserials.property_dict import PropertyDict
6+
from pyserials.flatten import flatten

pkg/src/pyserials/flatten.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
def flatten(data: dict | list[dict]) -> dict | list[dict]:
2+
"""Flatten a nested dictionary into a single-level dictionary.
3+
4+
Parameters
5+
----------
6+
data
7+
A dictionary or a list of dictionaries to flatten.
8+
9+
Returns
10+
-------
11+
If `data` is a dictionary, returns a flattened dictionary.
12+
If `data` is a list of dictionaries, returns a list of flattened dictionaries.
13+
"""
14+
if isinstance(data, dict):
15+
return _flatten(data)
16+
if isinstance(data, list):
17+
if not data:
18+
return []
19+
if not all(isinstance(item, dict) for item in data):
20+
raise ValueError("All items in the list must be dictionaries.")
21+
return [_flatten(item) for item in data]
22+
raise ValueError("Input must be a dictionary or a list of dictionaries.")
23+
24+
25+
def _flatten(data, output: dict | None = None, path: str | None = None):
26+
output = output if output is not None else {}
27+
if isinstance(data, str | int | float | bool | None):
28+
output[path] = data
29+
return output
30+
if isinstance(data, dict):
31+
for key, value in data.items():
32+
new_path = _flatten_key(path, key)
33+
_flatten(data=value, output=output, path=new_path)
34+
return output
35+
if isinstance(data, list):
36+
if len(data) == 0:
37+
output[path] = None
38+
return output
39+
if all(isinstance(val, str | int | float | bool | None) for val in data):
40+
output[path] = data[0] if len(data) == 1 else data
41+
return output
42+
if len(data) != 1:
43+
raise ValueError(f"Data at {path} is a list with more than one non-primitive element: {data}")
44+
return _flatten(data=data[0], output=output, path=path)
45+
raise ValueError(f"Unknown data type {type(data)} at {path}")
46+
47+
48+
def _flatten_key(path: str | None, key: str):
49+
if path:
50+
return f"{path}.{key}"
51+
return key

0 commit comments

Comments
 (0)