def unflatten(dictionary):
    resultDict = dict()
    for key, value in dictionary.items():
        parts = key.split(".")
        d = resultDict
        for part in parts[:-1]:
            if part not in d:
                d[part] = dict()
            d = d[part]
        d[parts[-1]] = value
    return resultDict
Answer from Messa on Stack Overflow
🌐
Wiktionary
en.wiktionary.org › wiki › unflatten
unflatten - Wiktionary, the free dictionary
From Wiktionary, the free dictionary · [edit] [edit] From un- +‎ flatten. [edit] unflatten (third-person singular simple present unflattens, present participle unflattening, simple past and past participle unflattened) (transitive) To restore (something flattened) to its previous form.
Discussions

Unflatten a Python dictionary - Stack Overflow
I have a dictionary, each value in the dictionary is a list with 0 or more elements representing parent: [children] relationships. For example, my_dict = {'435': ['188', '436', '439', '1038'], ... More on stackoverflow.com
🌐 stackoverflow.com
python - Make nested dictionary, unflatten - Stack Overflow
The question is how to achieve the unflatten to the nested dict the function below isnt working for lists ... What should the dictionary look like for the lists in lists example? More on stackoverflow.com
🌐 stackoverflow.com
How would I go about unflattening a complex nested dict with lists?
https://stackoverflow.com/questions/6027558/flatten-nested-dictionaries-compressing-keys More on reddit.com
🌐 r/learnpython
24
0
July 11, 2021
python - Unflatten Dictionary Structure to Nested Dictionary - Stack Overflow
I'm trying to unflatten a list of dictionary items to a nested dictionary structure which should contain the following structure Bus Message Fieldname I currently have a way to get the More on stackoverflow.com
🌐 stackoverflow.com
December 8, 2021
🌐
GitHub
github.com › dairiki › unflatten
GitHub - dairiki/unflatten: Python library to unpack flat dictionaries to a dict with nested dicts and/or lists · GitHub
Unflatten takes a single argument which should either be a dict (or an object with a dict-like .items() or .iteritems() method) or a sequence of (key, value) pairs. All keys in the dict or sequence must be strings.
Starred by 24 users
Forked by 6 users
Languages: Python
🌐
PyPI
pypi.org › project › flatten-dict
flatten-dict · PyPI
>>> from pprint import pprint >>> from flatten_dict import unflatten >>> flat_dict = { ... ('a',): '0', ... ('b', 'a'): '1.0', ... ('b', 'b'): '1.1', ... ('c', 'a'): '2.0', ... ('c', 'b', 'a'): '2.1.0', ... ('c', 'b', 'b'): '2.1.1', ... } >>> pprint(unflatten(flat_dict)) {'a': '0', 'b': {'a': '1.0', 'b': '1.1'}, 'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}} >>> flat_dict = { ...
🌐
PyPI
pypi.org › project › unflatten
unflatten · PyPI
Unflatten takes a single argument which should either be a dict (or an object with a dict-like .items() or .iteritems() method) or a sequence of (key, value) pairs. All keys in the dict or sequence must be strings.
      » pip install unflatten
    
Published: Sep 05, 2024
Version: 0.2.0
🌐
GitHub
github.com › ianlini › flatten-dict
GitHub - ianlini/flatten-dict: A flexible utility for flattening and unflattening dict-like objects in Python. · GitHub
This package provides a function flatten() for flattening dict-like objects in Python (tested with 3.10-3.15). It also provides some key joining methods (reducer), and you can choose the reducer you want or even implement your own reducer. You can also invert the resulting flat dict using unflatten().
Author: ianlini
Find elsewhere
Top answer
1 of 2
1

You can do it with loop. Is it what you want following?

my_dict = {'435': ['188', '436', '439', '1038'], '188': ['198'], '436': ['86', '115', '437', '444', '626', '650'], '439': [], '1038': ['733', '1037'], '198': [], '86': [], '115': [], '437': [], '444': [], '626': [], '650': [], '733': ['14'], '1037': [], '14': []}

table = {}
roots = set(my_dict)
for name, children in my_dict.items():
    table.setdefault(name, {'name': name})
    if children:
        table[name]['children'] = [
            table.setdefault(child, {'name': child})
            for child in children
        ]
        roots -= set(children)
result = {k: v for k, v in table.items() if k in roots}
print(list(result.values()))

output:

[{'name': '435', 'children': [{'name': '188', 'children': [{'name': '198'}]}, {'name': '436', 'children': [{'name': '86'}, {'name': '115'}, {'name': '437'}, {'name': '444'}, {'name': '626'}, {'name': '650'}]}, {'name': '439'}, {'name': '1038', 'children': [{'name': '733', 'children': [{'name': '14'}]}, {'name': '1037'}]}]}]

explanation:

  • table holds all items(name and children data).
  • If an item has children, register them to table by dict.setdefault.
  • roots contains all items that doen't belong any other items.
  • At last, filter only items which are in roots.
2 of 2
0

try using

# Python code to demonstrate  
# converting multi-d list into 1d list 
# using chain.from_iterables 

# import chain 
from itertools import chain 

ini_list = {'435': ['188', '436', '439', '1038'], '188': ['198'], '436': ['86', '115', '437', '444', '626', '650'], '439': [], '1038': ['733', '1037'], '198': [], '86': [], '115': [], '437': [], '444': [], '626': [], '650': [], '733': ['14'], '1037': [], '14': []}

# printing initial list 
for key in ini_list:

   # converting 2d list into 1d 
   # using chain.from_iterables 
   flatten_list = list(chain.from_iterable(ini_list[key])) 

   # printing flatten_list 
   print ("final_result", str(flatten_list)) 

Extrapolated solution from here: Geeks for Geeks I'm sure this can be optimized further but this should work and essentially throw everything into a single list within each dict position print the result and then initialize with the next dict key-value.

Hope that helps. If so, please mark as answer. Thanks

🌐
pytz
pythonhosted.org › flattery
flattery - fast flattening and unflattening of nested Python data
import sys from flattery import unflatten cols = [ "time", "request.method", "request.uri", "response.status", "response.size" ] for line in sys.stdin: fields = line.rstrip('\r\n').split(len(cols)-1) values = dict([(cols[i],fields[i]) for i in xrange(len(cols))]) record = unflatten(values) # do something with the record...
Top answer
1 of 2
1

Here is a solution using a tree of dict:

import collections

def tree():
    return collections.defaultdict(tree)


def unflatten(pair_list):
    root = tree()
    for mount, path in pair_list:
        parts = mount.split(":")
        curr = root
        for part in parts[:-1]:
            index = int(part[1:-1]) if part[0] == "[" else part
            curr = curr[index]
        part = parts[-1]
        index = int(part[1:-1]) if part[0] == "[" else part
        curr[index] = path
    return root

With the following input:

pair_list = [
  ['mounts:device', '/dev/sda3'],
  ['mounts:fstype:[0]', 'ext1'],
  ['mounts:fstype:[1]', 'ext3'],
  ['mounts:test:lala:fstype:[0]:[0]', 'abc']
]

You'll get:

{
    "mounts": {
        "fstype": {
            "0": "ext1",
            "1": "ext3"
        },
        "test": {
            "lala": {
                "fstype": {
                    "0": {
                        "0": "abc"
                    }
                }
            }
        },
        "device": "/dev/sda3"
    }
}

Then you can use the recursive function make_listbellow to turn the integer indexes in a list.

def make_list(root):
    if isinstance(root, str):
        return root
    keys = list(root.keys())
    if all(isinstance(k, int) for k in keys):
        values = [None] * (max(keys) + 1)
        for k in keys:
            values[k] = make_list(root[k])
        return values
    else:
        return {k: make_list(v) for k, v in root.items()}

Here is the result with the pair_list:

flat = unflatten(pair_list)
flat = make_list(flat)

You'll get:

{'mounts': {'device': '/dev/sda3',
            'fstype': ['ext1', 'ext3'],
            'test': {'lala': {'fstype': [['abc']]}}}}

Is it fine?

2 of 2
0
input1=[
  ['mounts:device', '/dev/sda3'],
  ['mounts:fstype:[0]', 'ext1'],
  ['mounts:fstype:[1]', 'ext3']
]
input2={x[1]:x[0].split(':')[1] for x in input1}
input3=['ext3', 'ext1', '/dev/sda3']
input4=['fstype', 'fstype', 'device']
res={}
for x,y in zip(input3, input4):
    res.setdefault(y,[]).append(x)
res1=res.keys()
res2=res.values()
res3=[x[0] for x in res2 if len(x)==1]+[x for x in res2 if len(x)>1]
result=dict(zip(res1,res3))

print result

Output :

{'device': '/dev/sda3', 'fstype': ['ext3', 'ext1']}
🌐
Blogger
explaincode11.blogspot.com › 2011 › 06 › python-unflatten-dict.html
Python - Unflatten dict -
November 10, 2017 - def unflatten(dictionary): resultdict = dict() key, value in dictionary.iteritems(): parts = key.split(".") d = resultdict part in parts[:-1]: if part not in d: d[part] = dict() d = d[part] d[parts[-1]] = value return resultdict · Get link · Facebook · X · Pinterest ·
🌐
Tradukka
tradukka.com › dictionary › english dictionary › 🇺🇸 what is unflatten?
🇺🇸 What is unflatten? | Tradukka
11 hours ago - What is unflatten? unflatten meaning and definition. To restore (something flattened) to its previous form.
🌐
PyPI
pypi.org › project › flatten-json
flatten-json · PyPI
from flatten_json import unflatten_list dic = { 'a': 1, 'b_0': 1, 'b_1': 2, 'c_a': 'a', 'c_b_0': 1, 'c_b_1': 2, 'c_b_2': 3 } unflatten_list(dic)
🌐
Reddit
reddit.com › r/learnpython › how would i go about unflattening a complex nested dict with lists?
r/learnpython on Reddit: How would I go about unflattening a complex nested dict with lists?
July 11, 2021 -

I need to flatten and unflatten a dict. I've figured out how to flatten it. As the dict is complex, this would be a representation of it:

di = {'a': [{'b': 'c', 'd': 'e'}, {'f': 'g'}, {'h': ['i']}]}

Flattening it gives me this:

flat_di = {'a.0.b': 'c', 'a.0.d': 'e', 'a.1.f': 'g', 'a.2.h.0': 'i'}

I've been trying to unflatten this for a while but my brain breaks when I try to figure it out. I know it's some form of recursion.

🌐
Wiktionary
en.wiktionary.org › wiki › unflattened
unflattened - Wiktionary, the free dictionary
From Wiktionary, the free dictionary · [edit] [edit] From un- +‎ flattened. [edit] unflattened (not comparable) Not flattened. [edit] From unflatten +‎ -ed. [edit] unflattened · simple past and past participle of unflatten · Retrieved from "https://en.wiktionary.org/w/index.php?titl...
Top answer
1 of 2
1

Using a defaultdict saves you a lot of hassle having to conditionally set up the structure of the dictionary:

>>> signals = [{"bus":"BUS_A", "message":"MSG_1", "fieldname":"Signal1"},
...            {"bus":"BUS_A", "message":"MSG_1", "fieldname":"Signal2"},
...            {"bus":"BUS_B", "message":"MSG_2", "fieldname":"Signal3"},
...            {"bus":"BUS_B", "message":"MSG_2", "fieldname":"Signal4"}]
>>> from collections import defaultdict
>>> buses = defaultdict(lambda: defaultdict(dict))
>>> for s in signals:
...     buses[s["bus"]][s["message"]][s["fieldname"]] = None
...
>>> buses
defaultdict(<function <lambda> at 0x00000265E25451F0>, {'BUS_A': defaultdict(<class 'dict'>, {'MSG_1': {'Signal1': None, 'Signal2': None}}), 'BUS_B': defaultdict(<class 'dict'>, {'MSG_2': {'Signal3': None, 'Signal4': None}})})

Without defaultdict you need to initialize each value to an empty dictionary as needed:

>>> buses = {}
>>> buses = {}
>>> for s in signals:
...     if s["bus"] not in buses:
...         buses[s["bus"]] = {}
...     if s["message"] not in buses[s["bus"]]:
...         buses[s["bus"]][s["message"]] = {}
...     buses[s["bus"]][s["message"]][s["fieldname"]] = None
...
>>> buses
{'BUS_A': {'MSG_1': {'Signal1': None, 'Signal2': None}}, 'BUS_B': {'MSG_2': {'Signal3': None, 'Signal4': None}}}
2 of 2
1

Here is one approach. It slims down some of the property juggling by starting with an object that already has 2 empty busses. This method is probably inferior to defaultdict, but it illustrates the logic behind unflattening your signals more directly. I can't pretend to know what you are doing, but this all seems like a bad way to do it, and to some degree pointless. What is the real outcome of this method ~ you assigned None to a signal name. All the data is already there, changing it's form is probably entirely unnecessary. Your 2 Busses should probably just be separate instantiations of a Bus class which has methods that can parse and organize the data that is fed to it. If you use a dataclass you could also use asdict (when/if necessary) to pass it's properties to whatever is expecting the data as a dict.

def unflatten(signals) -> dict:
    busses = {'BUS_A':dict(), 'BUS_B':dict()}
    for obj in signals:
        bus, msg, sig = obj['bus'], obj['message'], obj['fieldname']
        
        if not msg in busses[bus]:
            busses[bus][msg] = dict()
        
        busses[bus][msg][sig] = None
            
    return busses