docs: def from_keyed_iterable(iterable, key, filter_func=None):
      """Construct a dictionary out of an iterable, using an attribute name as
      the key. Optionally provide a filter function, to determine what should be
      kept in the dictionary."""
  
      generated = {}
  
      for element in iterable:
          try:
              k = getattr(element, key)
          except AttributeError:
              raise RuntimeError("{} does not have the keyed attribute: {}".format(
                  element, key
              ))
  
          if filter_func is None or filter_func(element):
              if k in generated:
                  generated[k] += [element]
              else:
                  generated[k] = [element]
  
      return generated