Home > Mobile >  Implementation of Max() function in python
Implementation of Max() function in python

Time:11-17

def my_max(*a):
    n = len(a)
    max_v = a[0]
    for i in range (1,n):
        if a[i] > max_v:
        max_v = a[i]
    return max_v  


def my_min(*a):
    n = len(a)
    min_v = a[0]
    for i in range (1,n):
        if a[i] < min_v:
            min_v = a[i]
    return min_v


test = [7, 4, 2, 6, 8]
assert max(test) == my_max(test) and min(test) == my_min(test)
assert max(7, 4, 2, 5) == my_max(7, 4, 2, 5) and min(7, 4, 2, 5) 
== my_min(7, 4, 2, 5)
print("pass")

I am trying to write the max() function of python in codes. If I add the asterisk in front of the input, it won't pass the first assertion. If I don't it wouldn't pass the second assertion. What should I write in input for it to pass both assertions like it does in max() function of python?

CodePudding user response:

Short answer: Use a star to collect the arguments in a tuple and then add a special case for a tuple of length one to handle a single iterable argument.

Source material: The C code that handles the logic can be found at: https://github.com/python/cpython/blob/da20d7401de97b425897d3069f71f77b039eb16f/Python/bltinmodule.c#L1708

Simplified pure python code: If you ignore the default and key keyword arguments, what's left simplifies to:

def mymax(*args):
    if len(args) == 0:
        raise TypeError('max expected at least 1 argument, got 0')
    if len(args) == 1:
        args = tuple(args[0])
    largest = args[0]
    for x in args[1:]:
        if x > largest:
            largest = x
    return largest

There are other nuances, but this should get you started.

Documentation: The special handling for the length one case versus other cases is documented here:

Return the largest item in an iterable or the largest of two or more arguments.

If one positional argument is provided, it should be an iterable. The largest item in the iterable is returned. If two or more positional arguments are provided, the largest of the positional arguments is returned.

More complete version: This includes some of aforementioned nuances like the key and default keyword arguments and the use of iterators instead of slices:

sentinel = object()

def mymax(*args, default=sentinel, key=None):
    """max(iterable, *[, default=obj, key=func]) -> value
    max(arg1, arg2, *args, *[, key=func]) -> value
    
    With a single iterable argument, return its biggest item. The
    default keyword-only argument specifies an object to return if
    the provided iterable is empty.
    With two or more arguments, return the largest argument.
    """
    if not args:
        raise TypeError('max expected at least 1 argument, got 0') 
    if len(args) == 1:
        it = iter(args[0])
    else:
        if default is not sentinel:
            raise TypeError('Cannot specify a default for max() with multiple positional arguments')
        it = iter(args)
    largest = next(it, sentinel)
    if largest is sentinel:
        if default is not sentinel:
            return default
        raise ValueError('max() arg is an empty sequence')
    if key is None:
        for x in it:
            if x > largest:
                largest = x
        return largest
    largest_key = key(largest)
    for x in it:
        kx = key(x)
        if kx > largest_key:
            largest = x
            largest_key = kx
    return largest

# This makes the tooltips nicer
# but isn't how the C code actually works
# and it is only half correct.
mymax.__text_signature__ = '($iterable, /, *, default=obj, key=func)'
  • Related