def cleanup(data, clean='<STR_LIT>', keep=None, copy=False):
adata = data.copy() if copy else data<EOL>keep = list([keep]) if isinstance(keep, str) else list() if keep is None else list(keep)<EOL>keep.extend(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'])<EOL>ann_dict = {'<STR_LIT>': adata.obs_keys(), '<STR_LIT>': adata.var_keys(),<EOL>'<STR_LIT>': adata.uns_keys(), '<STR_LIT>': list(adata.layers.keys())}<EOL>if '<STR_LIT:all>' not in clean:<EOL><INDENT>ann_dict = {ann: values for (ann, values) in ann_dict.items() if ann in clean}<EOL><DEDENT>for (ann, values) in ann_dict.items():<EOL><INDENT>for value in values:<EOL><INDENT>if value not in keep: del(getattr(adata, ann)[value])<EOL><DEDENT><DEDENT>return adata if copy else None<EOL>
Deletes attributes not needed.

    Arguments
    ---------
    data: :class:`~anndata.AnnData`
        Annotated data matrix.
    clean: `str` or list of `str` (default: `layers`)
        Which attributes to consider for freeing memory.
    keep: `str` or list of `str` (default: None)
        Which attributes to keep.
    copy: `bool` (default: `False`)
        Return a copy instead of writing to adata.

    Returns
    -------
    Returns or updates `adata` with selection of attributes kept.