Reputation: 414
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 :)
Upvotes: 2
Views: 1567
Reputation: 4075
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?
Upvotes: 0
Reputation: 1295
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.
Upvotes: 2