Python - generating parent/child dict structure
<p>I have method:</p>

<pre><code>@staticmethod
def get_blocks():
    """Public method that can be extended to add new blocks.

    First item is the most parent. Last item is the most child.
        Returns:
            blocks (list)
    """
    return ['header', 'body', 'footer']
</code></pre>

<p>As docstring describes, this method can be extended , to return any kind of blocks in particular order.</p>

<p>So I want to make a mapping that would indicate which block is parent/child to each other (only caring about "nearest" parent/child).</p>

<pre><code>def _get_blocks_mapping(blocks):
    mp = {'parent': {}, 'child': {}}
    if not blocks:
        return mp
    mp['parent'][blocks[0]] = None
    mp['child'][blocks[-1]] = None
    blocks_len = len(blocks)
    if blocks_len &gt; 1:
        mp['parent'][blocks[-1]] = blocks[-2]
        for i in range(1, len(blocks)-1):
            mp['parent'][blocks[i]] = blocks[i-1]
            mp['child'][blocks[i]] = blocks[i+1]
    return mp
</code></pre>

<p>So result if we have three blocks like in <code>get_blocks</code> method is this:</p>

<pre><code>{
        'parent': {
            'header': None,
            'body': 'header',
            'footer': 'body',
        },
        'child': {
            'header': 'body',
            'body': 'footer',
            'footer': None
        }
    }
</code></pre>

<p>Well it works, but it is kind of hacky to me. So maybe someone could suggest a better way to create such mapping? (or maybe there is some used way of creating parent/child mapping? Using different structure than I intend to use?)</p>

<p>You want to loop over the list in pairs, giving you the natural parent-child relationships:</p>

<pre><code>mp = {'parent': {}, 'child': {}}
if blocks:
    mp['parent'][blocks[0]] = mp['child'][blocks[-1]] = None
    for parent, child in zip(blocks, blocks[1:]):
        mp['parent'][child] = parent
        mp['child'][parent] = child
</code></pre>

<p><code>zip()</code> here pairs up each block with the next one in the list.</p>

<p>Demo:</p>

<pre><code>&gt;&gt;&gt; blocks = ['header', 'body', 'footer']
&gt;&gt;&gt; mp = {'parent': {}, 'child': {}}
&gt;&gt;&gt; if blocks:
...     mp['parent'][blocks[0]] = mp['child'][blocks[-1]] = None
...     for parent, child in zip(blocks, blocks[1:]):
...         mp['parent'][child] = parent
...         mp['child'][parent] = child
...
&gt;&gt;&gt; from pprint import pprint
&gt;&gt;&gt; pprint(mp)
{'child': {'body': 'footer', 'footer': None, 'header': 'body'},
 'parent': {'body': 'header', 'footer': 'body', 'header': None}}
</code></pre>

python list python-2.7 dictionary parent-child