I’m trying to design a custom min/max function that will always filter out every None from the inputs and if there is nothing else than None, it will also return None. I have found several answers that were partial to my question on how to create an ideal function that can handle absolutely anything. Same as the original min/max functions.
This is what I have created so far:
def min_null(q, *args): if isinstance(q, Iterable): return min(filter(lambda x: x is not None, q)) if any(q) else None else: return min_null([q, *args])
can you see any way this could fail? Or how it could be improved?
I will be glad to any feedback 🙂
Yes, one failure case is min_null([0, 0])
, which returns None
, rather than what I would expect, which is 0
. This could be fixed in a variety of ways, but one would be to take out the filter(lambda x: x is not None, q)
into a variable and then check it’s length, rather than just checking for any truthy values.
Sounds like you can use the min/max function with key=
and a custom comparison object that treats None
specially:
class Predicate: def __init__(self, item): self.item = item def __lt__(self, other): try: return self.item < other.item except TypeError: return False print(min([0, 1, 2, None, 3, 4], key=Predicate)) print(min([None], key=Predicate)) print(max([0, 1, 2, 3, None, 4, 5], key=Predicate)) print(max([None], key=Predicate))
Output:
0 None 5 None 0
Do you have some more examples or tests around what the expected results should be?