Package: dendrodict
Dictionary types that make it easier to work trees of nested dictionaries.Consider a nested regular dictionaries:d = {
    "en": {
        "gb": "English (United Kingdom)",
        "us": "English (United States)",
        "ca": "English (Canada)",
        "za": "English (South Africa)",
    },
    "no": {
        "nb": "Norwegian (Bokmål)",
        "nn": "Norwegian (Nynorsk)",
    },
    "fr": {
        "be": "French (Belgium)",
        "ca": "French (Canada)",
        "fr": "French (Standard)",
        "ch": "French (Switzerland)",
    }
}from which we can construct aDeepDict:>>> from dendrodict import DeepDict
>>> languages = DeepDict(d)Nested dictionaries can be accessed with single application of the square brackets get-item
operator:>>> languages["fr", "ca"]
'French (Canada)'or by using a tuple as a key:>>> languages[("no", "nb")]
'Norwegian (Bokmål)'The tuple key can also be used with other dictionary methods, such asget():>>> languages.get(("en", "us"))
'English (United States)'It’s still possible index the inner dictionary levels:>>> languages["en"]
DeepDict(
    {
        'gb': 'English (United Kingdom)',
        'us': 'English (United States)',
        'ca': 'English (Canada)',
        'za': 'English (South Africa)'
    }
)which means that separate lookup operations are still supported:>>> languages["en"]["za"]
'English (South Africa)'The tuple key form can also be used on construction, so flat dictionaries with tuple keys will be
expanded into nested dictionaries. Consider the following single-level mapping of tuple keys to
values:blocks = {
    ("mineral", "sandstone", "block"): "Sandstone",
    ("mineral", "sandstone", "chiseled"): "Sandstone (Chiseled)",
    ("mineral", "cobblestone", "block"): "Cobblestone",
    ("mineral", "cobblestone", "slab"): "Cobblestone (Slab)",
    ("mineral", "gold", "ore"): "Gold Ore",
    ("wood", "birch", "block"): "Birch",
    ("wood", "birch", "slab"): "Birch-Wood Slab",
    ("wood", "oak", "block"): "Oak",
    ("wood", "oak", "plank"): "Wooden Plank (Oak)",
}Created aDeepDictfrom this, gives a three-level structure:>>> minecraft = DeepDict(blocks)which we can see by converted back to dictionaries using theto_dict()method:>>> minecraft.to_dict()
{'mineral': {
    'cobblestone': {
        'block': 'Cobblestone',
        'slab': 'Cobblestone (Slab)'
    },
    'gold': {
        'ore': 'Gold Ore'
    },
    'sandstone': {
        'block': 'Sandstone',
        'chiseled': 'Sandstone (Chiseled)'
    }
},
'wood': {
    'birch': {
        'block': 'Birch',
        'slab': 'Birch-Wood Slab'
    },
    'oak': {
        'block': 'Oak',
        'plank': 'Wooden Plank (Oak)'}
    }
}Particularly when dealing with configuration data, it can be useful to be able to use dotted names
for access to nested items. UseDottedDeepDictfor this:from dendrodict import DottedDeepDict

displays = DottedDeepDict(
    {
        "resolution": {
            "vga": {
                "width": 640,
                "height": 480,
            },
            "wxga": {
                "width": 1280,
                "height": 800,
            },
            "wqhd": {
                "width": 2560,
                "height": 1440,
            },
        }
    }
)Dotted name syntax can be used for lookup:>>> displays["resolution.vga.width"]
640or for assignment at arbitrary levels:>>> displays["resolution.1080p.width"] = 1920
>>> displays["resolution.1080p.height"] = 1080Shallower levels are still available individually:>>> displays["resolution.1080p"]
DottedDeepDict({'width': 1920, 'height': 1080})and can be converted back to regular dictionaries:>>> displays["resolution.wqhd"].to_dict()
{'width': 2560, 'height': 1440}