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)