Bộ phận Python


133

Tôi đã cố gắng bình thường hóa một tập hợp các số từ -100 đến 0 thành phạm vi 10-100 và chỉ gặp vấn đề khi nhận thấy rằng ngay cả khi không có biến nào, điều này không đánh giá theo cách tôi mong đợi:

>>> (20-10) / (100-10)
0

Bộ phận nổi cũng không hoạt động:

>>> float((20-10) / (100-10))
0.0

Nếu một trong hai bên của phân chia được thả nổi, nó sẽ hoạt động:

>>> (20-10) / float((100-10))
0.1111111111111111

Mỗi bên trong ví dụ đầu tiên được đánh giá là một int có nghĩa là câu trả lời cuối cùng sẽ được chuyển thành int. Vì 0.111 nhỏ hơn 0,5, nó làm tròn thành 0. Nó không minh bạch theo quan điểm của tôi, nhưng tôi đoán đó là như vậy.

Giải thích là gì?



3
Adam, tôi vẫn không thích lời giải thích của bạn. Ví dụ đầu tiên là phép chia số nguyên, đơn giản trả về 0. Ví dụ thứ hai được ngoặc sai cho hiệu ứng bạn muốn.
Tổng thống James K. Polk

@GregS Ví dụ đầu tiên là vấn đề. Ví dụ thứ hai là giải thích và được viết sau câu hỏi đầu tiên. Tất cả các câu trả lời dưới đây giải thích vấn đề rất tốt, đặc biệt là của @KennyTM. Điều quan trọng cần lưu ý là sự cố ban đầu của tôi chỉ là sự cố trên Python 2.x chứ không phải 3. Có một chút không tin rằng hành vi sẽ thay đổi như vậy nhưng bây giờ tôi biết, tôi sẽ sử dụng từ bộ phận nhập khẩu trong tương lai và sử dụng 3 .x hành vi. Chúc mừng.
Adam Nelson

1
Adam, xin vui lòng sửa EDIT cuối cùng của bạn. Phía bên phải không có gì đặc biệt với nó; để một phép chia được thả nổi, tử số hoặc mẫu số (hoặc cả hai) cần phải nổi. Nếu bạn nghĩ rằng bạn đã đọc trong các tài liệu rằng phía bên tay phải cần phải nổi, thì tài liệu đó sẽ bị sai ngữ pháp và nên được sửa chữa, hoặc bạn đã hiểu nhầm nó. Bạn có thấy một ví dụ, có lẽ, và sau đó ngoại suy một quy tắc ra khỏi nó?
tzot

Câu trả lời:


246

Bạn đang sử dụng Python 2.x, trong đó các phép chia số nguyên sẽ cắt bớt thay vì trở thành số dấu phẩy động.

>>> 1 / 2
0

Bạn nên tạo một trong số chúng float:

>>> float(10 - 20) / (100 - 10)
-0.1111111111111111

hoặc from __future__ import division, mà các lực lượng /chấp nhận hành vi của Python 3.x luôn trả về một số float.

>>> from __future__ import division
>>> (10 - 20) / (100 - 10)
-0.1111111111111111

10
Nếu bạn sử dụng, from __future__ import divisionbạn có thể có hành vi phân chia kiểu C cũ bằng cách sử dụng hai dấu gạch chéo (ví dụ: 1 // 2sẽ dẫn đến 0). Xem Pep 238 Thay đổi Người vận hành Bộ phận
Người dùng

1
@ Người dùng Không cần nhập từ __future__. Trong cả Python 2 và 3 đều được //đề cập __floordiv__()theo mặc định.
Casimir

21

Bạn đang đặt Số nguyên vào để Python trả lại cho bạn một số nguyên :

>>> 10 / 90
0

Nếu bạn thực hiện điều này cho một float sau đó, việc làm tròn sẽ được thực hiện, nói cách khác, 0 số nguyên sẽ luôn trở thành 0 float.

Nếu bạn sử dụng float ở hai bên của bộ phận thì Python sẽ cho bạn câu trả lời mà bạn mong đợi.

>>> 10 / 90.0
0.1111111111111111

Vì vậy, trong trường hợp của bạn:

>>> float(20-10) / (100-10)
0.1111111111111111
>>> (20-10) / float(100-10)
0.1111111111111111

11

Bạn cần thay đổi nó thành một float TRƯỚC KHI bạn thực hiện phép chia. Đó là:

float(20 - 10) / (100 - 10)

4
@Adam Nelson: Hoạt động chính xác cho tôi. Kiểm tra dấu ngoặc đơn của bạn.
Fred Larson

Thật ra, tôi đã sai - nhưng sau khi xem các tài liệu, người ta nên chọn mặt phải trước.
Adam Nelson

10
@Adam: Không quan trọng là bên nào trước.
kennytm

11

Trong Python 2.7, /toán tử là một phép chia số nguyên nếu đầu vào là số nguyên:

>>>20/15
1

>>>20.0/15.0
1.33333333333

>>>20.0/15
1.33333333333

Trong Python 3.3, /toán tử là một phép chia float ngay cả khi các đầu vào là số nguyên.

>>> 20/15
1.33333333333

>>>20.0/15
1.33333333333

Để phân chia số nguyên trong Python 3, chúng tôi sẽ sử dụng //toán tử.

Các //nhà điều hành là một nhà điều hành phân chia số nguyên trong cả hai Python 2.7 và Python 3.3.

Trong Python 2.7 và Python 3.3:

>>>20//15
1

Bây giờ, xem so sánh

>>>a = 7.0/4.0
>>>b = 7/4
>>>print a == b

Đối với chương trình trên, đầu ra sẽ là Sai trong Python 2.7 và True trong Python 3.3.

Trong Python 2.7 a = 1.75 và b = 1.

Trong Python 3.3 a = 1.75 và b = 1.75, chỉ vì /là một phép chia float.


8

Nó phải làm với phiên bản python mà bạn sử dụng. Về cơ bản, nó chấp nhận hành vi C: nếu bạn chia hai số nguyên, kết quả sẽ được làm tròn xuống một số nguyên. Ngoài ra, hãy nhớ rằng Python thực hiện các thao tác từ trái sang phải, đóng vai trò khi bạn đánh máy.

Ví dụ: Vì đây là một câu hỏi luôn xuất hiện trong đầu tôi khi tôi đang thực hiện các phép toán số học (tôi nên chuyển đổi thành float và số nào), một ví dụ từ khía cạnh đó được trình bày:

>>> a = 1/2/3/4/5/4/3
>>> a
0

Khi chúng ta chia số nguyên, không ngạc nhiên khi nó được làm tròn thấp hơn.

>>> a = 1/2/3/4/5/4/float(3)
>>> a
0.0

Nếu chúng ta đánh máy số nguyên cuối cùng để thả nổi, chúng ta vẫn sẽ nhận được số không, vì vào thời điểm số của chúng ta được chia cho số float đã trở thành 0 do phân chia số nguyên.

>>> a = 1/2/3/float(4)/5/4/3
>>> a
0.0

Kịch bản tương tự như trên nhưng thay đổi kiểu chữ nổi gần hơn một chút về phía bên trái.

>>> a = float(1)/2/3/4/5/4/3
>>> a
0.0006944444444444445

Cuối cùng, khi chúng ta đánh máy số nguyên đầu tiên để nổi, kết quả là số nguyên mong muốn, vì bắt đầu từ phân chia đầu tiên, tức là số ngoài cùng bên trái, chúng ta sử dụng số float.

Thêm 1: Nếu bạn đang cố gắng trả lời rằng để cải thiện đánh giá số học, bạn nên kiểm tra điều này

Thêm 2: Hãy cẩn thận với kịch bản sau đây:

>>> a = float(1/2/3/4/5/4/3)
>>> a
0.0

4

Chỉ định một float bằng cách đặt một '.' sau số cũng sẽ làm cho nó mặc định nổi.

>>> 1 / 2
0

>>> 1. / 2.
0.5

2

Tạo ít nhất một trong số chúng nổi, sau đó sẽ là phân chia float, không phải là số nguyên:

>>> (20.0-10) / (100-10)
0.1111111111111111

Đúc kết quả để nổi là quá muộn.


1

Trong python cv2không cập nhật tính toán phân chia. vì vậy, bạn phải bao gồm from __future__ import division trong dòng đầu tiên của chương trình.


0

Dù bằng cách nào, đó là phân chia số nguyên. 10/90 = 0. Trong trường hợp thứ hai, bạn chỉ đang chuyển 0 sang số float.

Hãy thử chuyển một trong các toán hạng của "/" thành float:

float(20-10) / (100-10)

0

Bạn đang chuyển sang nổi sau khi phân chia đã xảy ra trong ví dụ thứ hai của bạn. Thử cái này:

float(20-10) / float(100-10)

0

Tôi hơi ngạc nhiên khi không ai đề cập rằng người đăng ban đầu có thể thích những con số hợp lý . Nếu bạn quan tâm đến điều này, Sage chương trình dựa trên Python có sự hỗ trợ của bạn . (Hiện tại vẫn dựa trên Python 2.x, mặc dù 3.x đang được tiến hành.)

sage: (20-10) / (100-10)
1/9

Đây không phải là một giải pháp cho tất cả mọi người, vì nó thực hiện một số bước chuẩn bị trước nên những con số này không phải intlà, mà là Integercác yếu tố của lớp Sage . Tuy nhiên, đáng nói là một phần của hệ sinh thái Python.


0

Cá nhân tôi thích chèn một 1. *ngay từ đầu. Vì vậy, biểu thức trở thành một cái gì đó như thế này:

1. * (20-10) / (100-10)

Như tôi luôn làm một bộ phận cho một số công thức như:

accuracy = 1. * (len(y_val) - sum(y_val)) / len(y_val)

vì vậy không thể chỉ đơn giản là thêm một lượt .0thích 20.0. Và trong trường hợp của tôi, gói bằng một float()có thể mất một chút khả năng đọc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.