docs: def from_dataset(cls, base, method='isel', default_slice=None,
                       decoder=None, auto_update=None, prefer_list=False,
                       squeeze=True, attrs=None, load=False, **kwargs):
          """
          Construct an ArrayList instance from an existing base dataset
  
          Parameters
          ----------
          base: xarray.Dataset
              Dataset instance that is used as reference
          %(InteractiveArray.update.parameters.method)s
          %(InteractiveBase.parameters.auto_update)s
          prefer_list: bool
              If True and multiple variable names pher array are found, the
              :class:`InteractiveList` class is used. Otherwise the arrays are
              put together into one :class:`InteractiveArray`.
          default_slice: indexer
              Index (e.g. 0 if `method` is 'isel') that shall be used for
              dimensions not covered by `dims` and `furtherdims`. If None, the
              whole slice will be used.
          decoder: CFDecoder
              The decoder that shall be used to decoder the `base` dataset
          squeeze: bool, optional
              Default True. If True, and the created arrays have a an axes with
              length 1, it is removed from the dimension list (e.g. an array
              with shape (3, 4, 1, 5) will be squeezed to shape (3, 4, 5))
          attrs: dict, optional
              Meta attributes that shall be assigned to the selected data arrays
              (additional to those stored in the `base` dataset)
          load: bool or dict
              If True, load the data from the dataset using the
              :meth:`xarray.DataArray.load` method. If :class:`dict`, those will
              be given to the above mentioned ``load`` method
  
          Other Parameters
          ----------------
          %(setup_coords.parameters)s
  
          Returns
          -------
          ArrayList
              The list with the specified :class:`InteractiveArray` instances
              that hold a reference to the given `base`"""
          try:
              load = dict(load)
          except (TypeError, ValueError):
              def maybe_load(arr):
                  return arr.load() if load else arr
          else:
              def maybe_load(arr):
                  return arr.load(**load)
  
          def iter_dims(dims):
              """Split the given dictionary into multiples and iterate over it"""
              if not dims:
                  while 1:
                      yield {}
              else:
                  dims = OrderedDict(dims)
                  keys = dims.keys()
                  for vals in zip(*map(cycle, map(safe_list, dims.values()))):
                      yield dict(zip(keys, vals))
  
          def recursive_selection(key, dims, names):
              names = safe_list(names)
              if len(names) > 1 and prefer_list:
                  keys = ('arr%i' % i for i in range(len(names)))
                  return InteractiveList(
                      starmap(sel_method, zip(keys, iter_dims(dims), names)),
                      auto_update=auto_update, arr_name=key)
              elif len(names) > 1:
                  return sel_method(key, dims, tuple(names))
              else:
                  return sel_method(key, dims, names[0])
  
          def ds2arr(arr):
              base_var = next(var for key, var in arr.variables.items()
                              if key not in arr.coords)
              attrs = base_var.attrs
              arr = arr.to_array()
              if 'coordinates' in base_var.encoding:
                  arr.encoding['coordinates'] = base_var.encoding[
                      'coordinates']
              arr.attrs.update(attrs)
              return arr
  
          if decoder is not None:
              def get_decoder(arr):
                  return decoder
          else:
              def get_decoder(arr):
                  return CFDecoder.get_decoder(base, arr)
  
          def add_missing_dimensions(arr):
              # add the missing dimensions to the dataset. This is not anymore
              # done by default from xarray >= 0.9 but we need it to ensure the
              # interactive treatment of DataArrays
              missing = set(arr.dims).difference(base.coords) - {'variable'}
              for dim in missing:
                  base[dim] = arr.coords[dim] = np.arange(base.dims[dim])
  
          if squeeze:
              def squeeze_array(arr):
                  return arr.isel(**{dim: 0 for i, dim in enumerate(arr.dims)
                                     if arr.shape[i] == 1})
          else:
              def squeeze_array(arr):
                  return arr
          if method == 'isel':
              def sel_method(key, dims, name=None):
                  if name is None:
                      return recursive_selection(key, dims, dims.pop('name'))
                  elif (isinstance(name, six.string_types) or
                        not utils.is_iterable(name)):
                      arr = base[name]
                  else:
                      arr = base[list(name)]
                  add_missing_dimensions(arr)
                  if not isinstance(arr, xr.DataArray):
                      arr = ds2arr(arr)
                  def_slice = slice(None) if default_slice is None else \
                      default_slice
                  decoder = get_decoder(arr)
                  dims = decoder.correct_dims(arr, dims)
                  dims.update({
                      dim: def_slice for dim in set(arr.dims).difference(
                          dims) if dim != 'variable'})
                  ret = squeeze_array(arr.isel(**dims))
                  # delete the variable dimension for the idims
                  dims.pop('variable', None)
                  ret.psy.init_accessor(arr_name=key, base=base, idims=dims)
                  return maybe_load(ret)
          else:
              def sel_method(key, dims, name=None):
                  if name is None:
                      return recursive_selection(key, dims, dims.pop('name'))
                  elif (isinstance(name, six.string_types) or
                        not utils.is_iterable(name)):
                      arr = base[name]
                  else:
                      arr = base[list(name)]
                  add_missing_dimensions(arr)
                  if not isinstance(arr, xr.DataArray):
                      arr = ds2arr(arr)
                  # idims will be calculated by the array (maybe not the most
                  # efficient way...)
                  decoder = get_decoder(arr)
                  dims = decoder.correct_dims(arr, dims)
                  if default_slice is not None:
                      dims.update({
                          key: default_slice for key in set(arr.dims).difference(
                              dims) if key != 'variable'})
                  # the sel method does not work with slice objects
                  if any(isinstance(idx, slice) for idx in dims.values()):
                      # ignore method argument
                      ret = squeeze_array(arr.sel(**dims))
                  else:
                      ret = squeeze_array(arr.sel(method=method, **dims))
                  ret.psy.init_accessor(arr_name=key, base=base)
                  return maybe_load(ret)
          if 'name' not in kwargs:
              default_names = list(
                  key for key in base.variables if key not in base.coords)
              try:
                  default_names.sort()
              except TypeError:
                  pass
              kwargs['name'] = default_names
          names = setup_coords(**kwargs)
          # check coordinates
          possible_keys = ['t', 'x', 'y', 'z', 'name'] + list(base.dims)
          for key in set(chain(*six.itervalues(names))):
              utils.check_key(key, possible_keys, name='dimension')
          instance = cls(starmap(sel_method, six.iteritems(names)),
                         attrs=base.attrs, auto_update=auto_update)
          # convert to interactive lists if an instance is not
          if prefer_list and any(
                  not isinstance(arr, InteractiveList) for arr in instance):
              # if any instance is an interactive list, than convert the others
              if any(isinstance(arr, InteractiveList) for arr in instance):
                  for i, arr in enumerate(instance):
                      if not isinstance(arr, InteractiveList):
                          instance[i] = InteractiveList([arr])
              else:  # put everything into one single interactive list
                  instance = cls([InteractiveList(instance, attrs=base.attrs,
                                                  auto_update=auto_update)])
                  instance[0].psy.arr_name = instance[0][0].psy.arr_name
          if attrs is not None:
              for arr in instance:
                  arr.attrs.update(attrs)
          return instance