2010-11-21 39 views
45

max(float('nan'), 1) đánh giá để nanPython: max/min chức năng được xây dựng trong phụ thuộc vào thứ tự tham số

max(1, float('nan')) đánh giá đến 1

Đó có phải là hành vi có ý định?


Cảm ơn câu trả lời.

max tăng ngoại lệ khi có thể lặp lại. Tại sao không phải max của Python sẽ tăng ngoại lệ khi nan có mặt? Hoặc ít nhất hãy làm điều gì đó hữu ích, như trả lại nan hoặc bỏ qua nan. Hành vi hiện tại là rất không an toàn và có vẻ hoàn toàn không hợp lý.

Tôi đã tìm thấy hậu quả đáng ngạc nhiên hơn nữa của hành vi này, vì vậy tôi vừa đăng một related question.

+0

Thực sự ... Nó dường như không để phá vỡ trên 'nan', vì 'max (0,5, float ('nan'), 1) 'trả về 1. – khachik

+2

@khachik: Tôi chỉ nói kết quả' max' phụ thuộc vào thứ tự của các tham số, điều này hơi bất ngờ với tôi, ngay cả khi nó chỉ xảy ra trong một ví dụ. Nhưng trên thực tế nó cũng hoạt động trên ví dụ của bạn: 'max (float ('nan'), 1, 0.5)' trả về nan. – max

+1

Lỗi không ở mức tối đa. Lỗi là thực tế rằng bạn đang sử dụng các dấu phẩy động và giả sử chúng có bất kỳ hành vi toán học có ý nghĩa nào. – Antimony

Trả lời

39
In [19]: 1>float('nan') 
Out[19]: False 

In [20]: float('nan')>1 
Out[20]: False 

Các phao nan không phải là lớn hơn hay nhỏ hơn số nguyên 1. max bắt đầu bằng cách chọn phần tử đầu tiên và chỉ thay thế phần tử đó khi tìm thấy phần tử lớn hơn.

In [31]: max(1,float('nan')) 
Out[31]: 1 

nan không lớn hơn 1, 1 được trả lại.

In [32]: max(float('nan'),1) 
Out[32]: nan 

Vì 1 không lớn hơn nan, nan được trả lại.


PS. Lưu ý rằng np.max xử lý float('nan') cách khác nhau:

In [36]: import numpy as np 
In [91]: np.max([1,float('nan')]) 
Out[91]: nan 

In [92]: np.max([float('nan'),1]) 
Out[92]: nan 

nhưng nếu bạn muốn bỏ qua np.nan s, bạn có thể sử dụng np.nanmax:

In [93]: np.nanmax([1,float('nan')]) 
Out[93]: 1.0 

In [94]: np.nanmax([float('nan'),1]) 
Out[94]: 1.0 
+6

Cảm ơn bạn đã trợ giúp. Hành vi khủng khiếp, mặc dù, IMO. – max

7

Tôi chưa từng thấy điều này trước đây, nhưng điều đó có ý nghĩa. Chú ý rằng nan là một đối tượng rất lạ:

>>> x = float('nan') 
>>> x == x 
False 
>>> x > 1 
False 
>>> x < 1 
False 

Tôi có thể nói rằng hành vi của max là undefined trong trường hợp này - những gì câu trả lời bạn mong chờ? Hành vi hợp lý duy nhất là giả định rằng các hoạt động là không đối xứng.


Chú ý rằng bạn có thể mô phỏng hành vi này bằng cách làm cho một lớp học bị hỏng:

>>> class Broken(object): 
...  __le__ = __ge__ = __eq__ = __lt__ = __gt__ = __ne__ = 
...  lambda self, other: False 
... 
>>> x = Broken() 
>>> x == x 
False 
>>> x < 1 
False 
>>> x > 1 
False 
>>> max(x, 1) 
<__main__.Broken object at 0x024B5B50> 
>>> max(1, x) 
1 
+0

Để so sánh NaN, bạn nên sử dụng hàm math.isnan – Andrew

1

Max hoạt động theo cách sau:

Mục đầu tiên được thiết lập là giá trị tối đa và sau đó là giá trị tiếp theo được so sánh với giá trị này.Sự so sánh sẽ luôn trả về False:

>>> float('nan') < 1 
False 
>>> float('nan') > 1 
False 

Vì vậy, nếu giá trị đầu tiên là nan, thì (do so sánh trả về false), nó sẽ không được thay thế khi bước tiếp theo.

OTOH nếu 1 là lần đầu tiên, điều tương tự cũng xảy ra: nhưng trong trường hợp này, vì 1 đã được đặt, nó sẽ là số tối đa.

Bạn có thể xác minh điều này trong mã python, chỉ cần nhìn lên chức năng min_max bằng Python/bltinmodule.c

Các vấn đề liên quan