nodes: 0, module; 1, function_definition; 2, function_name:_prepare_axes; 3, parameters; 4, block; 5, identifier:node; 6, identifier:sort_key; 7, expression_statement; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, for_statement; 13, return_statement; 14, comment:"""
      Sort axes and combine those that point to the same target and go
      in the same direction.
      """; 15, assignment; 16, assignment; 17, assignment; 18, assignment; 19, identifier:axis; 20, call; 21, block; 22, identifier:axes; 23, identifier:links; 24, attribute; 25, identifier:o_links; 26, attribute; 27, identifier:overlap; 28, set_comprehension; 29, identifier:axes; 30, list; 31, identifier:sorted; 32, argument_list; 33, if_statement; 34, expression_statement; 35, if_statement; 36, expression_statement; 37, identifier:node; 38, identifier:links; 39, identifier:node; 40, identifier:_overlapping_links; 41, identifier:ax2; 42, for_in_clause; 43, for_in_clause; 44, call; 45, keyword_argument; 46, comparison_operator:axis in overlap; 47, block; 48, assignment; 49, comparison_operator:axis in o_links; 50, block; 51, call; 52, identifier:ax; 53, identifier:links; 54, identifier:ax2; 55, call; 56, attribute; 57, argument_list; 58, identifier:key; 59, identifier:sort_key; 60, identifier:axis; 61, identifier:overlap; 62, continue_statement; 63, identifier:tgt; 64, subscript; 65, identifier:axis; 66, identifier:o_links; 67, expression_statement; 68, expression_statement; 69, attribute; 70, argument_list; 71, attribute; 72, argument_list; 73, identifier:links; 74, identifier:keys; 75, identifier:links; 76, identifier:axis; 77, assignment; 78, assignment; 79, identifier:axes; 80, identifier:append; 81, tuple; 82, identifier:o_links; 83, identifier:get; 84, identifier:ax; 85, list; 86, pattern_list; 87, expression_list; 88, identifier:axis; 89, binary_operator:'%s%s%s' % (
                  s, '&'.join(a[1:-1] for a in [axis] + o_links[axis]), e
              ); 90, identifier:axis; 91, identifier:tgt; 92, identifier:s; 93, identifier:e; 94, subscript; 95, subscript; 96, string; 97, tuple; 98, identifier:axis; 99, integer:0; 100, identifier:axis; 101, unary_operator; 102, string_content:%s%s%s; 103, identifier:s; 104, call; 105, identifier:e; 106, integer:1; 107, attribute; 108, generator_expression; 109, string; 110, identifier:join; 111, subscript; 112, for_in_clause; 113, string_content:&; 114, identifier:a; 115, slice; 116, identifier:a; 117, binary_operator:[axis] + o_links[axis]; 118, integer:1; 119, unary_operator; 120, list; 121, subscript; 122, integer:1; 123, identifier:axis; 124, identifier:o_links; 125, identifier:axis
code: def _prepare_axes(node, sort_key):
      """
      Sort axes and combine those that point to the same target and go
      in the same direction.
      """
      links = node.links
      o_links = node._overlapping_links
      overlap = {ax2 for ax in links for ax2 in o_links.get(ax, [])}
      axes = []
      for axis in sorted(links.keys(), key=sort_key):
          if axis in overlap: continue
          tgt = links[axis]
          if axis in o_links:
              s, e = axis[0], axis[-1]
              axis = '%s%s%s' % (
                  s, '&'.join(a[1:-1] for a in [axis] + o_links[axis]), e
              )
          axes.append((axis, tgt))
      return axes