code: def invert_dict(dict_, unique_vals=True):
      r
      if unique_vals:
          if isinstance(dict_, OrderedDict):
              inverted = OrderedDict((val, key) for key, val in dict_.items())
          else:
              inverted = {val: key for key, val in dict_.items()}
      else:
          # Handle non-unique keys using groups
          inverted = defaultdict(set)
          for key, value in dict_.items():
              inverted[value].add(key)
          inverted = dict(inverted)
      return inverted
docs: r"""
      Swaps the keys and values in a dictionary.
  
      Args:
          dict_ (dict): dictionary to invert
          unique_vals (bool): if False, inverted keys are returned in a set.
              The default is True.
  
      Returns:
          dict: inverted
  
      Notes:
          The must values be hashable.
  
          If the original dictionary contains duplicate values, then only one of
          the corresponding keys will be returned and the others will be
          discarded.  This can be prevented by setting `unique_vals=True`,
          causing the inverted keys to be returned in a set.
  
      CommandLine:
          python -m ubelt.util_dict invert_dict
  
      Example:
          >>> import ubelt as ub
          >>> dict_ = {'a': 1, 'b': 2}
          >>> inverted = ub.invert_dict(dict_)
          >>> assert inverted == {1: 'a', 2: 'b'}
  
      Example:
          >>> import ubelt as ub
          >>> dict_ = ub.odict([(2, 'a'), (1, 'b'), (0, 'c'), (None, 'd')])
          >>> inverted = ub.invert_dict(dict_)
          >>> assert list(inverted.keys())[0] == 'a'
  
      Example:
          >>> import ubelt as ub
          >>> dict_ = {'a': 1, 'b': 0, 'c': 0, 'd': 0, 'f': 2}
          >>> inverted = ub.invert_dict(dict_, unique_vals=False)
          >>> assert inverted == {0: {'b', 'c', 'd'}, 1: {'a'}, 2: {'f'}}