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 returnpyth
andruby
.
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 forlist.sort()
. Thedefault
argument specifies an object to return if the provided iterable is empty. If the iterable is empty and default is not provided, aValueError
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]
andheapq.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)))