Source code for schrodinger.utils.withnone

"""
Functions for working with lists that may contain `None`.
"""


class _NoItem:
    """
    Class to use in sort keys instead of None
    """

    def __lt__(self, other):
        return not isinstance(other, _NoItem)

    def __gt__(self, other):
        return False


NO_ITEM = _NoItem()


[docs]def sorted_with_none(items, *, key=None, reverse=False): items = list(items) sort_with_none(items, key=key, reverse=reverse) return items
[docs]def sort_with_none(items, *, key=None, reverse=False): if key is None: key = lambda x: x key_with_none = lambda x: NO_ITEM if x is None else key(x) items.sort(key=key_with_none, reverse=reverse)
[docs]def min_with_none(*args, key=None, default=None): return _minmax_with_none(args, min, "min_with_none", key, default)
[docs]def max_with_none(*args, key=None, default=None): return _minmax_with_none(args, max, "max_with_none", key, default)
def _minmax_with_none(args, minmax_func, name, key, default): if len(args) == 1: items = args[0] else: items = args if not items: if default is not None: return default else: raise ValueError(f"{name} arg is an empty sequence") filtered = [x for x in items if x is not None] if not filtered: return default return minmax_func(items, key=key, default=default)