def map_metabolites_to_structures(metabolites, compartments):
    """
    Map metabolites from the identifier namespace to structural space.

    Metabolites who lack structural annotation (InChI or InChIKey) are ignored.

    Parameters
    ----------
    metabolites : iterable
        The cobra.Metabolites to map.
    compartments : iterable
        The different compartments to consider. Structures are treated
        separately for each compartment.

    Returns
    -------
    dict
        A mapping from a cobra.Metabolite to its compartment specific
        structure index.

    """
    # TODO (Moritz Beber): Consider SMILES?
    unique_identifiers = ["inchikey", "inchi"]
    met2mol = {}
    molecules = {c: [] for c in compartments}
    for met in metabolites:
        ann = []
        for key in unique_identifiers:
            mol = met.annotation.get(key)
            if mol is not None:
                ann.append(mol)
        # Ignore metabolites without the required information.
        if len(ann) == 0:
            continue
        ann = set(ann)
        # Compare with other structures in the same compartment.
        mols = molecules[met.compartment]
        for i, mol_group in enumerate(mols):
            if len(ann & mol_group) > 0:
                mol_group.update(ann)
                # We map to the index of the group because it is hashable and
                # cheaper to compare later.
                met2mol[met] = "{}-{}".format(met.compartment, i)
                break
        if met not in met2mol:
            # The length of the list corresponds to the 0-index after appending.
            met2mol[met] = "{}-{}".format(met.compartment, len(mols))
            mols.append(ann)
    return met2mol
Map metabolites from the identifier namespace to structural space.

    Metabolites who lack structural annotation (InChI or InChIKey) are ignored.

    Parameters
    ----------
    metabolites : iterable
        The cobra.Metabolites to map.
    compartments : iterable
        The different compartments to consider. Structures are treated
        separately for each compartment.

    Returns
    -------
    dict
        A mapping from a cobra.Metabolite to its compartment specific
        structure index.