Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from functools import singledispatch
- from itertools import chain
- from typing import (Any,
- Dict,
- Iterable,
- List)
- Record = Dict[str, Any]
- def flatten(object_: Record,
- *,
- path_separator: str = '.') -> Iterable[Record]:
- """
- Flattens given JSON object into list of objects with non-nested values.
- >>> flatten({'a': 1})
- [{'a': 1}]
- >>> flatten({'a': [1, 2]})
- [{'a': 1}, {'a': 2}]
- >>> flatten({'a': {'b': None}})
- [{'a.b': None}]
- """
- keys = set(object_)
- result = [dict(object_)]
- while keys:
- key = keys.pop()
- new_result = []
- for index, record in enumerate(result):
- try:
- value = record[key]
- except KeyError:
- new_result.append(record)
- else:
- if isinstance(value, dict):
- del record[key]
- new_value = flatten_nested_objects(
- value,
- prefix=key + path_separator,
- path_separator=path_separator)
- keys.update(new_value.keys())
- new_result.append({**new_value, **record})
- elif isinstance(value, list):
- del record[key]
- new_value = [
- flatten_nested_objects(sub_value,
- prefix=key + path_separator,
- path_separator=path_separator)
- for sub_value in value]
- keys.update(chain.from_iterable(map(dict.keys, new_value)))
- new_result.extend({**sub_value, **record}
- for sub_value in new_value)
- else:
- new_result.append(record)
- result = new_result
- return result
- @singledispatch
- def flatten_nested_objects(object_: Any,
- *,
- prefix: str = '',
- path_separator: str) -> Any:
- return {prefix[:-len(path_separator)]: object_}
- @flatten_nested_objects.register(dict)
- def _(object_: Record,
- *,
- prefix: str = '',
- path_separator: str) -> Record:
- result = dict(object_)
- for key in list(result):
- result.update(flatten_nested_objects(result.pop(key),
- prefix=(prefix + key
- + path_separator),
- path_separator=path_separator))
- return result
- @flatten_nested_objects.register(list)
- def _(object_: List,
- *,
- prefix: str = '',
- path_separator: str) -> Record:
- return {prefix[:-len(path_separator)]: list(map(flatten_nested_objects,
- object_))}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement