Python - Leaf and Non-Leaf Nodes Dictionary


Dictionary is an important data structure in Python which consists of key value pairs. They were originally designed to be non−iterable objects. However recently Python extended its support for iteration of the dictionary objects too. A nested dictionary has nodes, leaf, non−nodes etc. In this article we will understand how to manipulate leaf and non−leaf nodes using dictionaries in Python.

What are leaf and non leaf nodes?

Before we deep dive into the codes we first need to understand what are the leaf and non leaf nodes in dictionary data types.

  • Leaf node:Those nodes which do not have any other child nodes. They are also referred to as the terminal nodes.

  • Non leaf node:Those nodes which have non zero children nodes. They are always positioned above the leaf nodes and therefore they never occupy the lowest position in the hierarchical structure.

Using Iteration Technique

One of the brute force methods which we can apply to find the leaf and non leaf node is to adopt the iteration technique. We can iterate over the nested dictionary and under each iteration we can check if the element has any further node connected (children). If it has children we will keep storing the node in the category of leaf node. On the other hand if it does not have any other children we will mark it as a non leaf node.

Example

In the following example we have created three functions namely is_leaf_node, find_leaf_nodes, find_non_leaf_nodes. Essentially they find if any node is a leaf node, find the leaf nodes and the non leaf nodes of the nested dictionary respectively.

def is_leaf_node(node, tree):
    if node not in tree:
        return False
    return "children" not in tree[node]
def find_leaf_nodes(tree):
    leaf_nodes = []
    for node in tree:
        if is_leaf_node(node, tree):
            leaf_nodes.append(node)
    return leaf_nodes
def find_non_leaf_nodes(tree):
    non_leaf_nodes = []
    for node in tree:
        if not is_leaf_node(node, tree):
            non_leaf_nodes.append(node)
    return non_leaf_nodes
tree = {"A": {"value": 1},"B": {"value": 2},"C": {"value": 3},"X": {"value": None,"children": ["A", "B"]},"Y": {"value": None,"children": ["C"]}}
leaf_nodes = find_leaf_nodes(tree)
print("Leaf nodes:", leaf_nodes)
non_leaf_nodes = find_non_leaf_nodes(tree)
print("Non-leaf nodes:", non_leaf_nodes)

Output

Leaf nodes: ['A', 'B', 'C']
Non-leaf nodes: ['X', 'Y']

Using List Comprehension

List comprehension is a popular method in Python to combine multiple expressions in a single line to produce the elements of a list. If the nested dictionary already has the nodes marked as whether they are leaf or non leaf nodes then we can adopt this approach.

Example

In the following example we have created two functions named find_leaf_nodes and find_non_leaf_nodes which uses the list comprehension to find the leaf and non leaf nodes. In the list comprehension we used the expression which checks if the value of 'is_leaf' is True. If it is True we have kept that for the leaf nodes and if it is False we have kept this in the category of non leaf nodes.

def find_leaf_nodes(tree):
    leaf_nodes = [node for node, data in tree.items() if data.get("is_leaf")]
    return leaf_nodes

def find_non_leaf_nodes(tree):
    non_leaf_nodes = [node for node, data in tree.items() if "children" in data]
    return non_leaf_nodes
tree = {"A": {"value": 1, "is_leaf": True},"B": {"value": 2,"is_leaf": True},"C": {"value": 3,"is_leaf": True},"X": {"value": None,"children": ["A", "B"]},"Y": {"value": None,"children": ["C"]}}
leaf_nodes = find_leaf_nodes(tree)
print("Leaf nodes:", leaf_nodes)
non_leaf_nodes = find_non_leaf_nodes(tree)
print("Non-leaf nodes:", non_leaf_nodes)

Output

Leaf nodes: ['A', 'B', 'C']
Non-leaf nodes: ['X', 'Y']

Using parent-child Relationships

If a dictionary maintains a parent, child relationship we can also utilize the list comprehension or similar methods. Although in classes like Nodes we can define the parent and child relationships using pointers and other approaches, in Python dictionaries we can only maintain relationships in terms of the key value pairs.

Example

In the following example we have used the list comprehension to find the leaf and the non leaf nodes. We first obtained all the key value pairs using the 'items' method in Python. Next check if the nodes are values of another node(which means it's a non leaf node).

def find_leaf_nodes(tree):
    leaf_nodes = [node for node, _ in tree.items() if node not in tree.values()]
    return leaf_nodes
def find_non_leaf_nodes(tree):
    non_leaf_nodes = [node for node, _ in tree.items() if node in tree.values()]
    return non_leaf_nodes
tree = {
    "A": None,
    "B": "X",
    "C": "Y",
    "X": "root",
    "Y": "root"
}
leaf_nodes = find_leaf_nodes(tree)
print("Leaf nodes:", leaf_nodes)
non_leaf_nodes = find_non_leaf_nodes(tree)
print("Non-leaf nodes:", non_leaf_nodes)

Output

Leaf nodes: ['A', 'B', 'C']
Non-leaf nodes: ['X', 'Y']

Conclusion

In this article we understood how to deal with the leaf and non leaf nodes in a nested dictionary. We used several approaches to perform the same like the iterations approach −which is a brute force approach. Next we also used list comprehensions and 'items' and 'values' methods. The answer to which method should be applied depends upon the structure of the dictionary.

Updated on: 18-Jul-2023

149 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements