Pregunta

One of my coworkers was using the builtin max function (on Python 2.7), and he found a weird behavior.

By mistake, instead of using the keyword argument key (as in key=lambda n: n) to pre-sort the list passed as a parameter, he did:

 >>> max([1,2,3,3], lambda n : n)
[1, 2, 3, 3]

He was doing what in the documentation is explained as:

If two or more positional arguments are provided, the largest of the positional arguments is returned., so now I'm curious about why this happens:

>>> (lambda n:n) < []
True
>>> def hello():
...     pass
... 
>>> hello < []
True
>>> len(hello)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'function' has no len()

I know it's not a big deal, but I'd appreciate if any of the stackoverflowers could explain how those comparisons are internally made (or point me into a direction where I can find that information). :-)

Thank you in advance!

¿Fue útil?

Solución

Python 2 orders objects of different types rather arbitrarily. It did this to make lists always sortable, whatever the contents. Which direction that comparison comes out as is really not of importance, just that one always wins. As it happens, the C implementation falls back to comparing type names; lambda's type name is function, which sorts before list.

In Python 3, your code would raise an exception instead:

>>> (lambda n: n) < []
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: function() < list()

because, as you found out, supporting arbitrary comparisons mostly leads to hard-to-crack bugs.

Otros consejos

Everything in Python (2) can be compared, but some are fairly nonsensical, as you've seen.

>>> (lambda n:n) < []
True

Python 3 resolves this, and produces exceptions instead.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top