code: def match_and_substitute_params(
      mapping: Optional[Union[Callable, Dict]] = None,
      data: Optional[Any] = None,
  ) -> Any:
      r"""
      用来实现将输入的 **batch** 或者输出的 **outputs** 通过 ``mapping`` 将键值进行更换的功能；
      该函数应用于 ``input_mapping`` 和 ``output_mapping``；
  
      * 对于 ``input_mapping``，该函数会在 :class:`~fastNLP.core.controllers.TrainBatchLoop` 中取完数据后立刻被调用；
      * 对于 ``output_mapping``，该函数会在 :class:`~fastNLP.core.Trainer` 的 :meth:`~fastNLP.core.Trainer.train_step`
        以及 :class:`~fastNLP.core.Evaluator` 的 :meth:`~fastNLP.core.Evaluator.train_step` 中得到结果后立刻被调用；
  
      转换的逻辑按优先级依次为：
  
      1. 如果 ``mapping`` 是一个函数，那么会直接返回 **mapping(data)**；
      2. 如果 ``mapping`` 是一个 **Dict**，那么 ``data`` 的类型只能为以下三种： ``[Dict, dataclass, Sequence]``；
  
          * 如果 ``data`` 是 **Dict**，那么该函数会将 ``data`` 的 ``key`` 替换为 **mapping[key]**；
          * 如果 ``data`` 是 **dataclass**，那么该函数会先使用 :func:`dataclasses.asdict` 函数将其转换为 **Dict**，然后进行转换；
          * 如果 ``data`` 是 **Sequence**，那么该函数会先将其转换成一个对应的字典::
  
              {
                  "_0": list[0],
                  "_1": list[1],
                  ...
              }
  
            然后使用 ``mapping`` 对这个字典进行转换，如果没有匹配上 ``mapping`` 中的 ``key`` 则保持 ``'_number'`` 这个形式。
  
      :param mapping: 用于转换的字典或者函数；当 ``mapping`` 是函数时，返回值必须为字典类型；
      :param data: 需要被转换的对象；
      :return: 转换后的结果；
      """
      if mapping is None:
          return data
      if callable(mapping):
          # 注意我们在 `Trainer.extract_loss_from_outputs` 函数里会检查 outputs 的输出，outputs 的类型目前只支持 `Dict` 和 `dataclass`；
          return mapping(data)
  
      if not isinstance(mapping, Dict):
          raise ValueError(
              f"Parameter `mapping` should be of type `Dict` or `Callable`, not `{type(mapping)}`. This is caused"
              f"by your `input_mapping` or `output_mapping` parameter in your `Trainer` or `Evaluator`."
          )
      if (
          not isinstance(data, Dict)
          and not is_dataclass(data)
          and not isinstance(data, Sequence)
      ):
          raise ValueError(
              "Parameter `data` should be type `Dict` or `dataclass` when the other parameter `mapping` is "
              "type `Dict`."
          )
  
      # 如果 `data` 是一个 dataclass，那么先将其转换为一个 `Dict`；
      if is_dataclass(data):
          data = dataclass_to_dict(data)
      # 如果 `data` 是一个 List，那么我们同样先将其转换为一个 `Dict`，为 {"_0": list[0], "_1": list[1], ...}；
      elif isinstance(data, Sequence):
          data = {"_" + str(i): data[i] for i in range(len(data))}
  
      _new_data = {}
      for _name, _value in data.items():
          if _name in mapping:
              _new_data[mapping[_name]] = _value
          else:
              _new_data[_name] = _value
      return _new_data
  
imports: import functools
  import inspect
  from inspect import Parameter
  import dataclasses
  from dataclasses import is_dataclass
  from copy import deepcopy
  from collections import defaultdict, OrderedDict
  from typing import Callable, List, Any, Dict, AnyStr, Union, Mapping, Sequence
  from typing import Tuple, Optional
  from time import sleep
  import os
  from contextlib import contextmanager
  from functools import wraps
  from prettytable import PrettyTable
  from pathlib import Path
  from fastNLP.core.log import logger
label_desc: Use image node_id 8 for calling a global function with example usage: match_and_substitute_params(mapping, data) and returns: _new_data, data, mapping