class_docstr: The container for a dict of mutables.
  It looks like a regular Python dict, but it also works like a :class:`nni.mutable.Mutable` instance.
  
  :class:`MutableDict` will be the cartesian product of all the mutables in the dict.
  It's guaranteed to be ordered by the insertion order
  (based on a `language feature <https://mail.python.org/pipermail/python-dev/2017-December/151283.html>`__ of Python 3.7+).
  
  :class:`MutableDict` is usually used to make a mutable space human-readable.
  It can further be nested and used together with :class:`MutableList`. For example::
  
      >>> search_space = MutableDict({
      ...     'trainer': MutableDict({
      ...         'optimizer': Categorical(['sgd', 'adam']),
      ...         'lr': Numerical(1e-4, 1e-2, log_distributed=True),
      ...         'decay_epochs': MutableList([
      ...             Categorical([10, 20]),
      ...             Categorical([30, 50])
      ...         ]),
      ...     }),
      ...     'model': MutableDict({
      ...         'type': Categorical(['resnet18', 'resnet50']),
      ...         'pretrained': Categorical([True, False])
      ...     }),
      ... })
      >>> search_space.random()
      {'trainer': {'optimizer': 'sgd', 'lr': 0.000176, 'decay_epochs': [10, 30]}, 'model': {'type': 'resnet18', 'pretrained': True}}
  
  There is a fundamental difference between the key appeared in the dict,
  and the label of the mutables. The key is used to access the mutable and make the frozen dict more human-readable.
  Yet the label is used to identify the mutable in the whole search space, and typically used by search algorithms.
  In the example above, although the each variable have the keys like ``'optimizer'``, ``'lr'``, ``'type'``,
  their label is still not specified and thus auto-generated::
  
      >>> search_space['trainer']['optimizer'].label
      'global/1'
      >>> search_space.simplify()
      {
          'global/1': Categorical(['sgd', 'adam'], label='global/1'),
          'global/2': Numerical(0.0001, 0.01, label='global/2'),
          'global/3': Categorical([10, 20], label='global/3'),
          'global/4': Categorical([30, 50], label='global/4'),
          'global/5': Categorical(['resnet18', 'resnet50'], label='global/5'),
          'global/6': Categorical([True, False], label='global/6')
      }
      >>> search_space.freeze({
      ...     'global/1': 'adam',
      ...     'global/2': 0.0001,
      ...     'global/3': 10,
      ...     "global/4': 50,
      ...     'global/5': 'resnet50',
      ...     'global/6': False
      ... })
      {'trainer': {'optimizer': 'adam', 'lr': 0.0001, 'decay_epochs': [10, 50]}, 'model': {'type': 'resnet50', 'pretrained': False}}
  
  Here's another example where label is manually specified to indicate the relationship between the mutables::
  
      >>> search_space = MutableList([
      ...     MutableDict({
      ...         'in_features': Categorical([10, 20], label='hidden_dim'),
      ...         'out_features': Categorical([10, 20], label='hidden_dim') * 2,
      ...     }),
      ...     MutableDict({
      ...         'in_features': Categorical([10, 20], label='hidden_dim') * 2,
      ...         'out_features': Categorical([10, 20], label='hidden_dim') * 4,
      ...     }),
      ... ])
      >>> search_space.random()
      [{'in_features': 20, 'out_features': 40}, {'in_features': 40, 'out_features': 80}]
  
  Parameters
  ----------
  mutables
      :class:`MutableDict` can be instantiated in one of two ways.
      Either you pass a dictionary to mutables, or you pass the mutables as keyword arguments
      (where keyword named ``mutables`` should be avoided).
      It's not encouraged to put non-mutable objects in the dict, but it's allowed,
      in which case they will be simply ignored.
  
  Examples
  --------
  The following two usages are equivalent::
  
      >>> MutableDict({'a': Categorical([1, 2]), 'b': Categorical([3, 4])})
      MutableDict({'a': Categorical([1, 2], label='global/1'), 'b': Categorical([3, 4], label='global/2')})
      >>> MutableDict(a=Categorical([1, 2]), b=Categorical([3, 4]))
      MutableDict({'a': Categorical([1, 2], label='global/3'), 'b': Categorical([3, 4], label='global/4')})
code: def __delitem__(self, key: str) -> None:
      del self.mutables[key]
  
imports: from __future__ import annotations
  from typing import Any, Iterable, Iterator, Mapping, Callable, Sequence
  from .exception import SampleValidationError
  from .mutable import Mutable, Sample, LabeledMutable, _mutable_equal
label_desc: Use image node_id 9 for calling the MutableDict obj's underlying member method code with example usage: obj.__delitem__(key) without return types