Skip to content

Instantly share code, notes, and snippets.

@jfear
Last active October 12, 2020 17:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfear/b14658b54d5309ed2343e7bc6f4c151b to your computer and use it in GitHub Desktop.
Save jfear/b14658b54d5309ed2343e7bc6f4c151b to your computer and use it in GitHub Desktop.
Flatten nested dict/lists into a single list.
def flatten_nested(content: Union[list, dict, ChainMap]) -> List[Union[str, int, float]]:
"""Flatten an arbitrary nested dictionary.
Useful for flattening file patterns from a Yaml config.
Example:
>>> content = {"one": ["one_a", "one_b"], "two": "two_a"}
>>> sorted(flatten_nested(content))
["one_a", "one_b", "two_a"]
"""
def gen(iter: Union[list, dict, ChainMap, str, int, float]):
if isinstance(iter, (dict, ChainMap)):
yield from flatten_nested(list(iter.values()))
elif isinstance(iter, list):
for item in iter:
yield from flatten_nested(item)
else:
yield iter
return list(gen(content))
flatten_items = [
(
{
"lvl1": {
"lvl1a": "lvl1a",
"lvl1b": ["lvl1bi", "lvl1bii"],
"lvl1c": {
"lvl1ca": "lvl1ca",
"lvl1cb": "lvl1cb",
"lvl1cd": ["lvl1cdi", "lvl1cdii"],
},
},
},
["lvl1a", "lvl1bi", "lvl1bii", "lvl1ca", "lvl1cb", "lvl1cdi", "lvl1cdii"],
),
(
ChainMap({"lvl1a": "lvl1a", "lvl1b": ["lvl1bi", "lvl1bii"]}, {"lvl1c": "lvl1ca"}),
["lvl1a", "lvl1bi", "lvl1bii", "lvl1ca"],
),
]
@pytest.mark.parametrize("nested_content,expected_content", flatten_items)
def test_flatten_nested(nested_content, expected_content):
flattened_content = flatten_nested(nested_content)
assert sorted(flattened_content) == sorted(expected_content)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment