Source code for utilitools.utilities.flatten

import itertools


[docs]def flatten(iterable, /, *, dictionaries='keys', levels=None, types=None): """ | Flatten an iterable with multiple levels of nesting. :param iterable: | Iterable to be flattened. :type iterable: collections.Iterable :param dictionaries: | The way iterates over dictionaries. | The possible options are `items`, `keys`, and `values`. | By default, it will iterate on `keys`. :type dictionaries: str :param levels: | Nesting levels we want to flatten in the iterable. | By default, will be set to `float('inf')`. :type levels: int :param types: | Base types that we will not refer to in flattening. | By default, both `bytes` and `str` are predefined. :type types: tuple[type] :return: An iterator with flatten items. :rtype: collections.Iterator """ levels = float('inf') if levels is None else levels types = (bytes, str) if types is None else (bytes, str) + types def recursive_flatten(item, level): if level > levels or isinstance(item, types) or not hasattr(item, '__iter__'): yield item elif isinstance(item, dict): if dictionaries == 'items': for item in itertools.chain(*item.items()): yield from recursive_flatten(item, level + 1) elif dictionaries in ['keys', 'values']: for item in getattr(item, dictionaries)(): yield from recursive_flatten(item, level + 1) else: for item in iter(item): yield from recursive_flatten(item, level + 1) yield from recursive_flatten(iterable, 0)