Home > OS >  Build a tree from a list of objects
Build a tree from a list of objects

Time:01-25

I am trying to build a tree from a list of objects, which are characterised by several properties. Each object can have 3 properties that play a role in building a tree, that is velocity altitude exposure.

#Data structure

class Test():
   pass

tests = []
for el in data:
   test = Test()
   test.velocity = el[0] #100km/h or 120km/h or 140km/h
   test.altitude = el[1] #20m or 40m or 60m
   test.exposure = el[2] #10uSv or 20uSv or 30uSv
   #more data is assigned which is not shown as irrelevant
   tests.append(test)

# I am trying to build a data tree like the one below.
# Obviously it would be different than this one and depend on actual data input.
# Example built statically using anytree

Tests
├── 100km/h
│   ├── 20m
│   │   └── 10uSv
│   ├── 40m
│   │   └── 10uSv
│   └── 60m
│       └── 20uSv
├── 120km/h
│   ├── 40m
│   │   ├── 20uSv
│   │   └── 30uSv
│   └── 60m
│       ├── 20uSv
│       └── 30uSv
└── 140km/h
    └── 20m
        └── 30uSv

Although this problem looks simple (might not be) I just can not figure it out.

Cheers!

CodePudding user response:

You dont provide original data, so I tried to guess them.

I started with constructing nested dicts and then converting them to anytree format with recursive function.

Here is the code:

import itertools

import anytree

data = [
    ['100km/h', '20m', '10uSv'],
    ['100km/h', '40m', '10uSv'],
    ['100km/h', '60m', '20uSv'],
    ['120km/h', '40m', '20uSv'],
    ['120km/h', '40m', '30uSv'],
    ['120km/h', '60m', '20uSv'],
    ['120km/h', '60m', '30uSv'],
    ['140km/h', '20m', '30uSv'],
]

# Construct nested dicts
res = {'Tests': {}}

for a, b, c in data:
    res['Tests'].setdefault(a, {}).setdefault(b, {}).setdefault(c, True)

__import__('pprint').pprint(res)
# {'Tests': {'100km/h': {'20m': {'10uSv': True},
#                        '40m': {'10uSv': True},
#                        '60m': {'20uSv': True}},
#            '120km/h': {'40m': {'20uSv': True, '30uSv': True},
#                        '60m': {'20uSv': True, '30uSv': True}},
#            '140km/h': {'20m': {'30uSv': True}}}}


# Convert nested dicts to anytree format
def dict_to_tree(d, parent=None):
    if isinstance(d, bool):
        return

    for key in d:
        node = anytree.Node(key, parent)
        dict_to_tree(d[key], node)

root = anytree.Node('Tests')
dict_to_tree(res['Tests'], root)

for pre, fill, node in anytree.RenderTree(root):
    print(f'{pre}{node.name}')
# Tests
# ├── 100km/h
# │   ├── 20m
# │   │   └── 10uSv
# │   ├── 40m
# │   │   └── 10uSv
# │   └── 60m
# │       └── 20uSv
# ├── 120km/h
# │   ├── 40m
# │   │   ├── 20uSv
# │   │   └── 30uSv
# │   └── 60m
# │       ├── 20uSv
# │       └── 30uSv
# └── 140km/h
#     └── 20m
#         └── 30uSv
  •  Tags:  
  • Related