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)