docs: def get_stats_str(list_=None, newlines=False, keys=None, exclude_keys=[], lbl=None,
                    precision=None, axis=0, stat_dict=None, use_nan=False,
                    align=False, use_median=False, **kwargs):
      """
      Returns the string version of get_stats
  
      DEPRICATE in favor of ut.repr3(ut.get_stats(...))
  
      if keys is not None then it only displays chosen keys
      excluded keys are always removed
  
  
      CommandLine:
          python -m utool.util_dev --test-get_stats_str
  
      Example:
          >>> # ENABLE_DOCTEST
          >>> from utool.util_dev import *  # NOQA
          >>> list_ = [1, 2, 3, 4, 5]
          >>> newlines = False
          >>> keys = None
          >>> exclude_keys = []
          >>> lbl = None
          >>> precision = 2
          >>> stat_str = get_stats_str(list_, newlines, keys, exclude_keys, lbl, precision)
          >>> result = str(stat_str)
          >>> print(result)
          {'mean': 3, 'std': 1.41, 'max': 5, 'min': 1, 'nMin': 1, 'nMax': 1, 'shape': (5,)}
  
      SeeAlso:
          repr2
          get_stats
      """
      from utool.util_str import repr4
      import utool as ut
      # Get stats dict
      if stat_dict is None:
          stat_dict = get_stats(list_, axis=axis, use_nan=use_nan, use_median=use_median)
      else:
          stat_dict = stat_dict.copy()
      # Keep only included keys if specified
      if keys is not None:
          for key in list(six.iterkeys(stat_dict)):
              if key not in keys:
                  del stat_dict[key]
      # Remove excluded keys
      for key in exclude_keys:
          if key in stat_dict:
              del stat_dict[key]
      # apply precision
      statstr_dict = stat_dict.copy()
      #precisionless_types =  (bool,) + six.string_types
      if precision is not None:
          assert ut.is_int(precision), 'precision must be an integer'
          float_fmtstr = '%.' + str(precision) + 'f'
          for key in list(six.iterkeys(statstr_dict)):
              val = statstr_dict[key]
              isfloat = ut.is_float(val)
              if not isfloat and isinstance(val, list):
                  type_list = list(map(type, val))
                  if len(type_list) > 0 and ut.allsame(type_list):
                      if ut.is_float(val[0]):
                          isfloat = True
                          val = np.array(val)
              if isfloat:
                  if isinstance(val, np.ndarray):
                      strval = str([float_fmtstr % v for v in val]).replace('\'', '').lstrip('u')
                      #np.array_str((val), precision=precision)
                  else:
                      strval = float_fmtstr % val
                  if not strval.startswith('0'):
                      strval = strval.rstrip('0')
                      strval = strval.rstrip('.')
                  statstr_dict[key] = strval
              else:
                  if isinstance(val, np.ndarray):
                      strval = repr(val.tolist())
                  else:
                      strval = str(val)
                  statstr_dict[key] = strval
  
      # format the dictionary string
      stat_str  = repr4(statstr_dict, strvals=True, newlines=newlines)
      # add a label if requested
      if lbl is True:
          lbl = ut.get_varname_from_stack(list_, N=1)  # fancy
      if lbl is not None:
          stat_str = 'stats_' + lbl + ' = ' + stat_str
      if align:
          stat_str = ut.align(stat_str, ':')
      return stat_str