Private method to split a list of species into
        various partitions.

def _partition_species(composition, max_components=2):
        """
        Private method to split a list of species into
        various partitions.
        """

        def _partition(collection):
            # thanks https://stackoverflow.com/a/30134039

            if len(collection) == 1:
                yield [collection]
                return

            first = collection[0]
            for smaller in _partition(collection[1:]):
                # insert `first` in each of the subpartition's subsets
                for n, subset in enumerate(smaller):
                    yield smaller[:n] + [[first] + subset] + smaller[n + 1:]
                # put `first` in its own subset
                yield [[first]] + smaller

        def _sort_partitions(partitions_to_sort):
            """
            Sort partitions by those we want to check first
            (typically, merging two sites into one is the
            one to try first).
            """

            partition_indices = [(idx, [len(p) for p in partition])
                                 for idx, partition in enumerate(partitions_to_sort)]

            # sort by maximum length of partition first (try smallest maximums first)
            # and secondarily by number of partitions (most partitions first, i.e.
            # create the 'least disordered' structures first)
            partition_indices = sorted(partition_indices, key=lambda x: (max(x[1]), -len(x[1])))

            # merge at most max_component sites,
            # e.g. merge at most 2 species into 1 disordered site
            partition_indices = [x for x in partition_indices if max(x[1]) <= max_components]

            partition_indices.pop(0)  # this is just the input structure

            sorted_partitions = [partitions_to_sort[x[0]] for x in partition_indices]

            return sorted_partitions

        collection = list(composition.keys())
        partitions = list(_partition(collection))
        partitions = _sort_partitions(partitions)

        return partitions