<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 python_subdict - Documentation
The markdown version of this document is here.
Installing
You can pip-install python_subdict in your environment by typing the following code on your shell
Step1:  If we need only the keys 'a' and 'd', we can do this
Step2:  We can also specify 'subkeys' by using a dotted-syntax
Step3:  The dotted-syntax can have any needed level of depth
Step4:  Specifying invalid keys behavior
Let's consider the following dict from now on
Step5:  By default, invalid keys passed to the extract_subdict function are ignored
Step6:  However, by passing True to the strict parameter of the function, invalid keys will raise a KeyError exception
Step7:  Successive extractions
Extracting only 'name' and 'albums' from the person dict
Step8:  Now, extracting only the 'name' of each album
Step9:  The result is the following
<ASSISTANT_TASK:>
Python Code:
d = {
    'a': 'A',
    'b': 'B',
    'c': 'C',
    'd': {
        'x': 'D_X',
        'y': 'D_Y',
        'z': {
            'I': 'D_Z_I',
            'II': {
                '1': 'D_Z_II_1',
                '2': 'D_Z_II_2'
            },
            'III': 'D_Z_III'
        }
    }
}
Explanation: python_subdict - Documentation
The markdown version of this document is here.
Installing
You can pip-install python_subdict in your environment by typing the following code on your shell:
pip install subdict
Usage example
As an example, let's say that we have the following dict:
End of explanation
from subdict import extract_subdict  # The main function of the library
from pprint import pprint  # Just for a nice presentation here
pprint( extract_subdict(d, ['a', 'd']) )
Explanation: If we need only the keys 'a' and 'd', we can do this:
End of explanation
pprint( extract_subdict(d, ['a', 'd.x', 'd.z']) )
Explanation: We can also specify 'subkeys' by using a dotted-syntax:
End of explanation
pprint( extract_subdict(d, ['a', 'd.z.II.1']) )
Explanation: The dotted-syntax can have any needed level of depth:
End of explanation
person = {
    'name': 'John Frusciante',
    'birth': '1970-03-05',
    'city': {
        'name': 'New York City',
        'state': {'name': 'New York', 'country': 'USA'}
    },
    'albums': [
        {
            'year': 2001,
            'name': 'To Record Only Water For Ten Days',
            'label': {
                'name': 'Warner Bros Records',
                'link': 'https://en.wikipedia.org/wiki/Warner_Bros._Records'
            }
        },
        {
            'year': 2004,
            'name': 'Shadows Collide With People',
            'label': {
                'name': 'Warner Bros Records',
                'link': 'https://en.wikipedia.org/wiki/Warner_Bros._Records'
            }
        },
        {
            'year': 2009,
            'name': 'The Empyrean',
            'label': {
                'name': 'Record Collection',
                'link': 'https://en.wikipedia.org/wiki/Record_Collection'
            }
        }
    ]
}
Explanation: Specifying invalid keys behavior
Let's consider the following dict from now on:
End of explanation
extract_subdict(person, ['name', 'birth', 'hair_color'])  # 'hair_color' is invalid
Explanation: By default, invalid keys passed to the extract_subdict function are ignored:
End of explanation
extract_subdict(person, ['name', 'birth', 'hair_color'], strict=True)
Explanation: However, by passing True to the strict parameter of the function, invalid keys will raise a KeyError exception:
End of explanation
subdict = extract_subdict(person, ['name', 'albums'])
pprint(subdict)
Explanation: Successive extractions
Extracting only 'name' and 'albums' from the person dict:
End of explanation
for index in range(len(subdict['albums'])):
    subdict['albums'][index] = extract_subdict(subdict['albums'][index], ['name'])
Explanation: Now, extracting only the 'name' of each album:
End of explanation
pprint(subdict)
Explanation: The result is the following:
End of explanation
<END_TASK>