Search code examples
pythonsortingpython-2.7dictionaryhierarchical-data

Sorting a dictionary both hierarchically and alphabetically (Python)


I am using a Python dictionary (product_dict) to represent a hierarchy of a product and all its subparts. The dict's keys are unique IDs (UUID), and the values are Class objects containing all information about those parts, including:

part.name        # A string, containing the actual name of a component
part.idCode      # UUID of component
part.parent      # UUID of parent component
part.children    # List of UUIDs of child components
part.tier        # An integer that specifies its tier/level within the hierarchy

Now for the purpose of outputting the data in an orderly fashion, I wish to sort the parts both hierarchically and alphabetically. For hierarchical sorting using a tree structure, I have found the answer to this question to work great for printing: Sorting data hierarchically. For this example to work with my data structure, I have made some slight modifications:

class Node:
    def __init__(self, article):
        self.article = article
        self.children = []
        self.parent = None
        self.name = None 

    def printer(self, level=0):
        print ('{}{}'.format('\t' * level, self.name))
        for child in self.children:
            child.printer(level + 1)


class Tree:
    def __init__(self):
        self.nodes = {}

    def push(self, article, parent, name):                          
        if parent not in self.nodes:
            self.nodes[parent] = Node(parent)
        if article not in self.nodes:                              
            self.nodes[article] = Node(article)
        if parent == article:
            return
        self.nodes[article].name = name
        self.nodes[article].parent = self.nodes[parent]             
        self.nodes[parent].children.append(self.nodes[article])    

    @property
    def roots(self):
        return (x for x in self.nodes.values() if not x.parent)


t = Tree()

for idCode, part in product_dict.iteritems(): 
    t.push(idCode, part.parent, part.name)
for node in t.roots:
    node.printer()

Considering an example of my product being an aircraft, the output now looks as follows (the actual order varies):

Aircraft
    Systems
        Subsystem 2
        Subsystem 1
            Subsubsystem 1.1
    Engines
    Airframe
        Section 2
        Section 1
        Section 4
        Section 3

However, due to my limited understanding of Python at this stage, I am struggling to add alphabetical sorting to this routine (based on the part.name strings). I understand how the tree is built up, but I don't grasp the printing routine, and therefore fail to judge where to add a alphabetic sorting routine.

With the given example, my desired output should be:

Aircraft
    Airframe
        Section 1
        Section 2
        Section 3
        Section 4
    Engines     
    Systems
        Subsystem 1
            Subsubsystem 1.1
        Subsystem 2

Any help is greatly appreciated. I do not adhere to the hierarchical sorting method given above, so I am open to entirely different approaches.


Solution

  • It seems like the only thing you need to do is sort the children by name, when printing, i.e.

     for child in sorted(self.children, key = lambda x: x.name):
            child.printer(level + 1)