min() & max() vs sorted()

M

MRAB

Hi,

Some time after reading about Python 2.5 and how the built-in functions
'min' and 'max' will be getting a new 'key' argument, I wondered how
they would treat those cases where the keys were the same, for example:

L = ["four", "five"]
print min(L, key = len), max(L, key = len)

The result is:

('four', 'four')

I would've thought that min(...) should return the same as
sorted(...)[0] (which it does) and that max(...) should return the same
as sorted(...)[-1] (which it doesn't).

I think that's just down to a subtlety in the way that 'max' is written.
 
T

Tim Peters

[MRAB]
Some time after reading about Python 2.5 and how the built-in functions
'min' and 'max' will be getting a new 'key' argument, I wondered how
they would treat those cases where the keys were the same, for example:

L = ["four", "five"]
print min(L, key = len), max(L, key = len)

The result is:

('four', 'four')

min() and max() both work left-to-right, and return the minimal or
maximal element at the smallest index.
I would've thought that min(...) should return the same as
sorted(...)[0] (which it does)

It does, but only because Python's sort is stable, so that minimal
elements retain their original relative order. That implies that the
minimal element with smallest original index will end up at index 0
after sorting.
and that max(...) should return the same as sorted(...)[-1] (which it doesn't).

Right -- although I don't know why you'd expect that.
I think that's just down to a subtlety in the way that 'max' is written.

It's straightforward, skipping error cases:

def max(*args):
is_first_arg = True
for arg in args:
if is_first_arg:
winner = arg
is_first_arg = False
elif arg > winner: # only difference in min() is "<" here instead
winner = arg
return winner
 
M

MRAB

Tim said:
[MRAB]
Some time after reading about Python 2.5 and how the built-in functions
'min' and 'max' will be getting a new 'key' argument, I wondered how
they would treat those cases where the keys were the same, for example:

L = ["four", "five"]
print min(L, key = len), max(L, key = len)

The result is:

('four', 'four')

min() and max() both work left-to-right, and return the minimal or
maximal element at the smallest index.
It doesn't say that in the documentation.
I would've thought that min(...) should return the same as
sorted(...)[0] (which it does)

It does, but only because Python's sort is stable, so that minimal
elements retain their original relative order. That implies that the
minimal element with smallest original index will end up at index 0
after sorting.
and that max(...) should return the same as sorted(...)[-1] (which it doesn't).

Right -- although I don't know why you'd expect that.
Strings have index(), find(), etc which work left-to-right and
rindex(), rfind(), etc which work right-to-left.

Lists have index() but not rindex().

I just thought that if min() and max() work left-to-right then for
completeness there should also be rmin() and rmax(); alternatively,
min() should return sorted()[0] and max() should return sorted()[-1]
for symmetry (my personal preference).
 
T

Tim Peters

[MRAB]
Some time after reading about Python 2.5 and how the built-in functions
'min' and 'max' will be getting a new 'key' argument, I wondered how
they would treat those cases where the keys were the same, for example:

L = ["four", "five"]
print min(L, key = len), max(L, key = len)

The result is:

('four', 'four')

[Tim Peters]
min() and max() both work left-to-right, and return the minimal or
maximal element at the smallest index.
[MRAB]
It doesn't say that in the documentation.

Right, the /language/ doesn't define anything about which specific
minimal or maximal element is returned. Since you specifically
mentioned Python 2.5, I figured you were asking about CPython -- which
has always behaved in the way I explained.
I would've thought that min(...) should return the same as
sorted(...)[0] (which it does)
It does, but only because Python's sort is stable, so that minimal
elements retain their original relative order. That implies that the
minimal element with smallest original index will end up at index 0
after sorting.
and that max(...) should return the same as sorted(...)[-1] (which
it doesn't).
Strings have index(), find(), etc which work left-to-right and
rindex(), rfind(), etc which work right-to-left.

Lists have index() but not rindex().

I just thought that if min() and max() work left-to-right then for
completeness there should also be rmin() and rmax(); alternatively,
min() should return sorted()[0] and max() should return sorted()[-1]
for symmetry (my personal preference).

If you were to make either of those a feature request, I don't expect
they'd gain traction -- I expect "who cares?" would be the common
challenge, and "I do" wouldn't silence it ;-) Compelling use cases
sometimes work to get a new feature, but "completeness" or "symmetry"
almost never do on their own (they function more as sanity checks on
proposed solutions to use cases).
 
P

Paddy

MRAB said:
Tim said:
[MRAB]
Some time after reading about Python 2.5 and how the built-in functions
'min' and 'max' will be getting a new 'key' argument, I wondered how
they would treat those cases where the keys were the same, for example:

L = ["four", "five"]
print min(L, key = len), max(L, key = len)

The result is:

('four', 'four')

min() and max() both work left-to-right, and return the minimal or
maximal element at the smallest index.
It doesn't say that in the documentation.
I would've thought that min(...) should return the same as
sorted(...)[0] (which it does)

It does, but only because Python's sort is stable, so that minimal
elements retain their original relative order. That implies that the
minimal element with smallest original index will end up at index 0
after sorting.
and that max(...) should return the same as sorted(...)[-1] (which it doesn't).

Right -- although I don't know why you'd expect that.
Strings have index(), find(), etc which work left-to-right and
rindex(), rfind(), etc which work right-to-left.

Lists have index() but not rindex().

I just thought that if min() and max() work left-to-right then for
completeness there should also be rmin() and rmax(); alternatively,
min() should return sorted()[0] and max() should return sorted()[-1]
for symmetry (my personal preference).

Strange, but I've never thought of min and max in the way you do. If
anything I think of them as being distinct from sort; a way to get the
appropriate values without going to the bother of a full sort. After
doing my excercises on implementing sort routines, and reading about
cPythons sort algorithm, if I want just max or min, then I won't go
sorting in a hurry. I am quite happy with min and max just returning
the value.
With the addition of the key then I might want the option of returning
key(value) instead of value, i.e. 4 instead of "four".

- Paddy.

P.S. I have not played with Python 2.5 as yet
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,217
Latest member
IRMNikole

Latest Threads

Top