<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def save(fname, data):
 """Saves a list of arrays or a dict of str->array to file. Examples of filenames: - ``/path/to/file`` - ``s3://my-bucket/path/to/file`` (if compiled with AWS S3 supports) - ``hdfs://path/to/file`` (if compiled with HDFS supports) Parameters fname : str The filename. data : NDArray, RowSparseNDArray or CSRNDArray, \ or list of NDArray, RowSparseNDArray or CSRNDArray, \ or dict of str to NDArray, RowSparseNDArray or CSRNDArray The data to save. Examples -------- [<NDArray 2x3 @cpu(0)>, <NDArray 1x4 @cpu(0)>] {'y': <NDArray 1x4 @cpu(0)>, 'x': <NDArray 2x3 @cpu(0)>} """

    if isinstance(data, NDArray):
        data = [data]
        handles = c_array(NDArrayHandle, [])
    if isinstance(data, dict):
        str_keys = data.keys()
        nd_vals = data.values()
        if any(not isinstance(k, string_types) for k in str_keys) or \
           any(not isinstance(v, NDArray) for v in nd_vals):
            raise TypeError('save only accept dict str->NDArray or list of NDArray')
        keys = c_str_array(str_keys)
        handles = c_handle_array(nd_vals)
    elif isinstance(data, list):
        if any(not isinstance(v, NDArray) for v in data):
            raise TypeError('save only accept dict str->NDArray or list of NDArray')
        keys = None
        handles = c_handle_array(data)
    else:
        raise ValueError("data needs to either be a NDArray, dict of str, NDArray pairs "
                         "or a list of NDarrays.")
    check_call(_LIB.MXNDArraySave(c_str(fname),
                                  mx_uint(len(handles)),
                                  handles,
                                  keys))