Home > database >  max() with key argument python
max() with key argument python

Time:01-08

I know a bit about how key argument is used in python max(). max(("pyth", "lua", "ruby"), key=len) will return pyth and ruby. However, max((31, 13, 11), key=lambda x: sum(int(i) for i in str(x))) will only give me 31 (13 should be returned as well), or max((13, 31, 11), key=lambda x: sum(int(i) for i in str(x))) will only give me 13 (31 should be returned as well). Can someone explain this? Many thanks.

CodePudding user response:

Regarding your contention:

max(("pyth", "lua", "ruby"), key=len) will return pyth and ruby.

No, it really won't:

>>> max(("pyth", "lua", "ruby"), key=len)
'pyth'

The max functions returns only one value, the maximum value. With default method, it doesn't normally matter since two values of 31 can return either sensibly.

But, if you conflate visibly different items so that they have the same "value", you'll be able to tell the difference when printing.

By the way, you always get the first one found during iteration, as per the docs (my emphasis in the final paragraph, which is the paragraph making it clear only one item, and which in the case of duplicates, is returned):

max(iterable, *, key=None)
max(iterable, *, default, key=None)
max(arg1, arg2, *args, key=None)

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.

There are two optional keyword-only arguments. The key argument specifies a one-argument ordering function like that used for list.sort(). The default argument specifies an object to return if the provided iterable is empty. If the iterable is empty and default is not provided, a ValueError is raised.

If multiple items are maximal, the function returns the first one encountered. This is consistent with other sort-stability preserving tools such as sorted(iterable, key=keyfunc, reverse=True)[0] and heapq.nlargest(1, iterable, key=keyfunc).

CodePudding user response:

As max() can only return one value, you'll need a custom function to return a list of all values that equate to the maximum sum of digits.

You could do this:

from functools import cache

v = (31, 13, 11)

@cache
def sum_digits(n): # much faster than converting to strings and slicing
    s = 0
    while n > 0:
        s  = n % 10
        n //= 10
    return s

def getvals(v):
    m = sorted(v, key=sum_digits, reverse=True)

    result = [m[0]] # effectively the max value

    for e in m[1:]:
        if sum_digits(e) != sum_digits(m[0]):
            break
        result.append(e) # has same sum of digits as the max value

    return result

print(getvals(v))

Output:

[31, 13]

CodePudding user response:

The (max) returns the largest item. If you want to find the maximum value based on the sum of the digits, you could try this.

max_value = max(iterable, key=lambda x: sum(int(i) for i in str(x)))
  • Related