문제

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!

도움이 되었습니까?

해결책

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.

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top