Ondrej
Ondrej

Reputation: 414

Python foolproof min/max function with None

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

Answers (2)

Terry Spotts
Terry Spotts

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

xavc
xavc

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

Related Questions