code: def _recursive_pairwise_outer_join(
      dataframes_to_merge,
      on,
      lsuffix,
      rsuffix,
      npartitions,
      shuffle_method,
  ):
      """
      Schedule the merging of a list of dataframes in a pairwise method. This is a recursive function that results
      in a much more efficient scheduling of merges than a simple loop
      from:
      [A] [B] [C] [D] -> [AB] [C] [D] -> [ABC] [D] -> [ABCD]
      to:
      [A] [B] [C] [D] -> [AB] [CD] -> [ABCD]
      Note that either way, n-1 merges are still required, but using a pairwise reduction it can be completed in parallel.
      :param dataframes_to_merge: A list of Dask dataframes to be merged together on their index
      :return: A single Dask Dataframe, comprised of the pairwise-merges of all provided dataframes
      """
      number_of_dataframes_to_merge = len(dataframes_to_merge)
  
      merge_options = {
          "on": on,
          "lsuffix": lsuffix,
          "rsuffix": rsuffix,
          "npartitions": npartitions,
          "shuffle_method": shuffle_method,
      }
  
      # Base case 1: just return the provided dataframe and merge with `left`
      if number_of_dataframes_to_merge == 1:
          return dataframes_to_merge[0]
  
      # Base case 2: merge the two provided dataframe to be merged with `left`
      if number_of_dataframes_to_merge == 2:
          merged_ddf = dataframes_to_merge[0].join(
              dataframes_to_merge[1], how="outer", **merge_options
          )
          return merged_ddf
  
      # Recursive case: split the list of dfs into two ~even sizes and continue down
      else:
          middle_index = number_of_dataframes_to_merge // 2
          merged_ddf = _recursive_pairwise_outer_join(
              [
                  _recursive_pairwise_outer_join(
                      dataframes_to_merge[:middle_index],
                      **merge_options,
                  ),
                  _recursive_pairwise_outer_join(
                      dataframes_to_merge[middle_index:],
                      **merge_options,
                  ),
              ],
              **merge_options,
          )
          return merged_ddf
  
imports: from __future__ import annotations
  import math
  import pickle
  import warnings
  from functools import partial, wraps
  import numpy
  import pandas
  from pandas.api.types import is_dtype_equal
  from tlz import merge_sorted, unique
  from dask.base import is_dask_collection, tokenize
  from dask.dataframe import methods
  from dask.dataframe.core import DataFrame, Index, Series, _concat, _deprecated_kwarg, _Frame, _maybe_from_pandas, is_broadcastable, map_partitions, new_dd_object, prefix_reduction, suffix_reduction
  from dask.dataframe.dispatch import group_split_dispatch, hash_object_dispatch
  from dask.dataframe.io import from_pandas
  from dask.dataframe.shuffle import partitioning_index, rearrange_by_divisions, shuffle, shuffle_group
  from dask.dataframe.utils import asciitable, check_meta, is_dataframe_like, is_series_like, make_meta, strip_unknown_categories
  from dask.highlevelgraph import HighLevelGraph
  from dask.layers import BroadcastJoinLayer
  from dask.utils import M, apply, get_default_shuffle_method
label_desc: Use image node_id 32 for calling a global function with example usage: _recursive_pairwise_outer_join(dataframes_to_merge, on, lsuffix, rsuffix, npartitions, shuffle_method) and returns: dataframes_to_merge, merged_ddf, merged_ddf