2013-09-23 37 views
48

Trong trường của tôi, rất phổ biến để làm vuông một số, vận hành chúng lại với nhau và lấy căn bậc hai của kết quả. Điều này được thực hiện trong định lý pythagore, và ví dụ tính toán RMS.Exponentiation in Python - tôi có nên sử dụng toán tử thay vì math.pow và math.sqrt không?

Trong NumPy, tôi đã làm những điều sau đây:

result = numpy.sqrt(numpy.sum(numpy.pow(some_vector, 2))) 

Và trong một cái gì đó trăn tinh khiết như thế này sẽ được dự kiến:

result = math.sqrt(math.pow(A, 2) + math.pow(B,2)) # example with two dimensions. 

Tuy nhiên, tôi đã sử dụng hình thức trăn tinh khiết này, vì Tôi thấy nó nhỏ gọn hơn, không độc lập về nhập khẩu và dường như tương đương:

result = (A**2 + B**2)**0.5 # two dimensions 
result = (A**2 + B**2 + C**2 + D**2)**0.5 

Tôi đã nghe một số người cho rằng các nhà điều hành ** là loại hack, và rằng bình phương một số bằng cách exponentiating nó bằng 0.5 không phải là như vậy có thể đọc được. Nhưng điều tôi muốn hỏi là:

"Có bất kỳ lý do tính toán nào để thích hai lựa chọn thay thế cũ hơn (các) thứ ba không?"

Cảm ơn bạn đã đọc!

+1

Đây có thể là một chủ đề có liên quan - http://stackoverflow.com/questions/327002/which-is-faster-in-python-x-5-or-math-sqrtx –

+1

Tôi có xu hướng để nghĩ rằng math.sqrt() có thể đọc được nhiều hơn() ** 0.5. –

+1

@Maxime, tôi sẽ đi xa hơn và chỉ sử dụng 'sqrt' với' từ sqrt nhập toán học. –

Trả lời

43

math.sqrt là việc thực hiện C của căn bậc hai và do đó khác nhau từ việc sử dụng các nhà điều hành ** mà thực hiện tích hợp pow chức năng của Python. Do đó, việc sử dụng math.sqrt thực sự mang lại một câu trả lời khác so với việc sử dụng toán tử ** và thực sự có lý do tính toán để thích thực hiện numpy hoặc math mô-đun hơn tích hợp sẵn. Cụ thể, các hàm sqrt có thể được thực hiện theo cách hiệu quả nhất có thể trong khi ** hoạt động trên một số lượng lớn các căn cứ và số mũ và có lẽ không được tối ưu hóa cho trường hợp cụ thể của căn bậc hai. Mặt khác, chức năng được xây dựng trong pow xử lý một vài trường hợp bổ sung như "số phức, số nguyên lũy vô biên và lũy thừa mô đun".

See this Stack Overflow question for more information on the difference between ** and math.sqrt.

Xét trong số đó là nhiều hơn "Pythonic", tôi nghĩ rằng chúng ta cần phải thảo luận về định nghĩa của từ đó. Từ the official Python glossary, nó nói rằng một đoạn mã hoặc ý tưởng là Pythonic nếu nó "theo sát các thành ngữ phổ biến nhất của ngôn ngữ Python, thay vì thực thi mã bằng cách sử dụng các khái niệm chung cho các ngôn ngữ khác."Trong mỗi ngôn ngữ khác tôi có thể nghĩ đến, có một số mô-đun toán học với các hàm căn bậc hai cơ bản. Tuy nhiên, có những ngôn ngữ thiếu một nhà điều hành công suất như **, ví dụ: C++. Vì vậy, ** có thể là Pythonic hơn. tùy thuộc vào trường hợp sử dụng.

+0

'operator.pow' rơi vào hỗn hợp ở đâu? –

+0

Câu trả lời tuyệt vời, đặc biệt là để lấy những gì có thể là một chủ đề 'được đánh giá cao' và tập trung vào OP, cũng như những người thuê Python cần thiết. Thanh danh. – GrayedFox

+0

Tuy nhiên, nếu đầu vào là số nguyên, ** hoặc hàm pow có sẵn có thể thích hợp hơn là tính toán: "Không giống như toán tử ** dựng sẵn, math.pow() chuyển đổi cả hai đối số thành kiểu float. Sử dụng ** hoặc hàm pow() tích hợp để tính toán các số nguyên chính xác. " - Tài liệu Python: thư viện toán học https://docs.python.org/2/library/math.html#power-and-logarithmic-functions – hyperGeoMetric

12

Ngay cả trong Python cơ sở bạn có thể làm việc tính toán ở dạng generic

result = sum(x**2 for x in some_vector) ** 0.5 

x ** 2 là chắc chắn không phải là một hack và tính toán thực hiện là như nhau (tôi đã kiểm tra với mã nguồn CPython). Tôi thực sự thấy nó dễ đọc hơn (và khả năng đọc được).

Sử dụng thay vì x ** 0.5 để lấy căn bậc hai không làm các tính toán chính xác giống như math.sqrt như cựu (có thể) được tính bằng logarit và sau này (có thể) bằng cách sử dụng hướng dẫn số cụ thể của bộ xử lý toán học.

Tôi thường sử dụng x ** 0.5 đơn giản chỉ vì tôi không muốn thêm math chỉ cho điều đó. Tôi mong đợi tuy nhiên một hướng dẫn cụ thể cho căn bậc hai để làm việc tốt hơn (chính xác hơn) hơn một hoạt động đa bước với logarit.

+2

Rõ ràng [không chính xác hơn] (http://stackoverflow.com/a/842358/199360) - nhưng [sqrt nhanh hơn] (http://stackoverflow.com/a/327011/199360). – adib

+0

Tại sao trình thông dịch Python không nhận ra x ** 0.5 là trường hợp đặc biệt? Sau khi tất cả 0,5 là một hằng số. – user3150208

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