nodes: 0, module; 1, function_definition; 2, function_name:group_by_key_func; 3, parameters; 4, block; 5, identifier:iterable; 6, identifier:key_func; 7, expression_statement; 8, expression_statement; 9, for_statement; 10, return_statement; 11, comment:"""
      Create a dictionary from an iterable such that the keys are the result of evaluating a key function on elements
      of the iterable and the values are lists of elements all of which correspond to the key.
  
      >>> def si(d): return sorted(d.items())
      >>> si(group_by_key_func("a bb ccc d ee fff".split(), len))
      [(1, ['a', 'd']), (2, ['bb', 'ee']), (3, ['ccc', 'fff'])]
      >>> si(group_by_key_func([-1, 0, 1, 3, 6, 8, 9, 2], lambda x: x % 2))
      [(0, [0, 6, 8, 2]), (1, [-1, 1, 3, 9])]
      """; 12, assignment; 13, identifier:item; 14, identifier:iterable; 15, block; 16, identifier:result; 17, identifier:result; 18, call; 19, expression_statement; 20, identifier:defaultdict; 21, argument_list; 22, call; 23, identifier:list; 24, attribute; 25, argument_list; 26, subscript; 27, identifier:append; 28, identifier:item; 29, identifier:result; 30, call; 31, identifier:key_func; 32, argument_list; 33, identifier:item
code: def group_by_key_func(iterable, key_func):
      """
      Create a dictionary from an iterable such that the keys are the result of evaluating a key function on elements
      of the iterable and the values are lists of elements all of which correspond to the key.
  
      >>> def si(d): return sorted(d.items())
      >>> si(group_by_key_func("a bb ccc d ee fff".split(), len))
      [(1, ['a', 'd']), (2, ['bb', 'ee']), (3, ['ccc', 'fff'])]
      >>> si(group_by_key_func([-1, 0, 1, 3, 6, 8, 9, 2], lambda x: x % 2))
      [(0, [0, 6, 8, 2]), (1, [-1, 1, 3, 9])]
      """
      result = defaultdict(list)
      for item in iterable:
          result[key_func(item)].append(item)
      return result