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
generator[0]("not subscriptable"). It complains aboutmin=args[0][0].Nonefirst and then check if it isNonewhen iterating over the generator (so you can set it to the first element) and afterwards (if there are no elements).argswill always be a tuple, so yourifblock will always be entered, and yourelseblock will never be entered. Furthermore, since bothifandelsehave an unconditionalreturninside them, your firstforloop will never get past the first iteration. You may as well remove it, and theargvcheck as well.