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)'
Answer from Raymond Hettinger on Stack OverflowImplementation of the max() function in Python - Stack Overflow
Creating a max function from scratch (python) - Stack Overflow
Min-max python v3 implementation - Stack Overflow
Ping in Python
Is max() an in-built function in Python?
What is the use of the max() and min() functions in Python?
What is the difference between the Python max() and min() functions?
You've got one line of code backwards. Your if statement is effectively saying that if item is greater than Max, set item to Max. You need to flip that to say if item is greater than Max, set Max to item.
if item > Max:
Max = item
return Max
Also, I'm not an expert in Python, but i think you need to change the List inside your function to match the parameter name, in this case args.
*args = list of arguments -as positional arguments
You are passing a list as an argument here. So your code should look something like this -
def maximum(nums):
Max = 0
for item in nums:
if item > Max:
Max=item
return Max
List = [1,5,8,77,24,95]
print maximum(List)
This would give you the result : 95.
On the other hand you can use the max built in function to get the maximum number in the list.
print max(List)
Here is my implementation:
def max(*args, **kwargs):
key = kwargs.get("key", lambda x: x)
if len(args) == 1:
args = args[0]
maxi = None
for i in args:
if maxi == None or key(i) > key(maxi):
maxi = i
return maxi
def min(*args, **kwargs):
key = kwargs.get("key", lambda x: x)
if len(args) == 1:
args = args[0]
mini = None
for i in args:
if mini == None or key(i) < key(mini):
mini = i
return mini
A little bit more concise than preview post.
The issue you are having is due to the fact that min has two function signatures. From its docstring:
min(...)
min(iterable[, key=func]) -> value
min(a, b, c, ...[, key=func]) -> value
So, it will accept either a single positional argument (an iterable, who's values you need to compare) or several positional arguments which are the values themselves. I think you need to test which mode you're in at the start of your function. It is pretty easy to turn the one argument version into the multiple argument version simply by doing args = args[0].
Here's my attempt to implement the function. key is a keyword-only argument, since it appears after *args.
def min(*args, key=None): # args is a tuple of the positional arguments initially
if len(args) == 1: # if there's just one, assume it's an iterable of values
args = args[0] # replace args with the iterable
it = iter(args) # get an iterator
try:
min_val = next(it) # take the first value from the iterator
except StopIteration:
raise ValueError("min() called with no values")
if key is None: # separate loops for key=None and otherwise, for efficiency
for val in it: # loop on the iterator, which has already yielded one value
if val < min_val
min_val = val
else:
min_keyval = key(min_val) # initialize the minimum keyval
for val in it:
keyval = key(val)
if keyval < min_keyval: # compare keyvals, rather than regular values
min_val = val
min_keyval = keyval
return min_val
Here's some testing:
>>> min([4, 5, 3, 2])
2
>>> min([1, 4, 5, 3, 2])
1
>>> min(4, 5, 3, 2)
2
>>> min(4, 5, 3, 2, 1)
1
>>> min(4, 5, 3, 2, key=lambda x: -x)
5
>>> min(4, -5, 3, -2, key=abs)
-2
>>> min(abs(i) for i in range(-10, 10))
0