Питонний поділ


133

Я намагався нормалізувати набір чисел від -100 до 0 до діапазону 10-100, і у мене були проблеми, лише помітивши, що навіть без змінних це зовсім не оцінює так, як я б очікував цього:

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

Поплавковий поділ також не працює:

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

Якщо будь-яка сторона поділу буде кинута на поплавок, вона буде працювати:

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

Кожна сторона в першому прикладі оцінюється як int, що означає, що остаточну відповідь буде подано на int. Оскільки 0,111 менший за 0,5, він кругляє до 0. Він не прозорий, на мою думку, але я думаю, що так.

Яке пояснення?



3
Адаме, мені все ще не подобається твоє пояснення. Перший приклад - це ціле ділення, яке просто повертає 0. Другий приклад неправильно скоплений дужкою для потрібного ефекту.
Президент Джеймс К. Полк

@GregS Першим прикладом була проблема. Другий приклад пояснювальний і був написаний після першого запитання. Усі наведені нижче відповіді дуже добре пояснюють це питання, особливо @KennyTM's. Важливо зазначити, що моя первісна проблема - це лише проблема на Python 2.x, а не 3. Це мало сумніву, що поведінка зміниться так, але тепер, коли я знаю, я буду використовувати з майбутнього відділу імпорту та використовувати 3 .x поведінка. Ура.
Адам Нельсон

1
Адаме, виправте останню редакцію. Права сторона не має нічого особливого до цього; для того, щоб поділ було плавким, чисельник чи знаменник (або обидва) повинні бути плаваючими. Якщо ви думаєте, що ви прочитали в документах про те, що права сторона повинна бути плаваючою, то або документація сильно сформульована і повинна бути виправлена, або ви неправильно її зрозуміли. Можливо, ви бачили приклад, а потім екстраполюєте правило з нього?
tzot

Відповіді:


246

Ви використовуєте Python 2.x, де цілі поділки будуть скорочуватися замість того, щоб стати числом з плаваючою точкою.

>>> 1 / 2
0

Ви повинні зробити один із них float:

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

або from __future__ import division, що змушує /прийняти поведінку Python 3.x, яка завжди повертає поплавок.

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

10
Якщо ви користуєтесь, from __future__ import divisionви можете отримати стару поведінку поділу в стилі С, використовуючи дві косої риси (наприклад, 1 // 2це призведе до 0). Див. Pep 238 Зміна оператора відділу
користувача

1
@User Немає потреби в імпорті з __future__. І в Python 2 і 3 //посилається на __floordiv__()за замовчуванням.
Казимир

21

Ви вводите цілі числа, щоб Python давав вам ціле число назад :

>>> 10 / 90
0

Якщо після цього ви передасте це поплавцю, то округлення вже буде зроблено, іншими словами, 0 ціле число завжди стане 0 float.

Якщо ви використовуєте поплавці з обох боків підрозділу, Python дасть вам відповідь, яку ви очікуєте.

>>> 10 / 90.0
0.1111111111111111

Тож у вашому випадку:

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

11

Вам потрібно змінити його на поплавок, перш ніж ви будете робити поділ. Це є:

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

4
@ Адам Нельсон: Мене працює правильно. Перевірте дужки.
Фред Ларсон

Насправді я помиляюся - але, подивившись на документи, слід спочатку відкинути праву сторону.
Адам Нельсон

10
@Adam: Не важливо спочатку на якій стороні.
kennytm

11

У Python 2.7 /оператор є цілим поділом, якщо входи цілі числа:

>>>20/15
1

>>>20.0/15.0
1.33333333333

>>>20.0/15
1.33333333333

У Python 3.3 /оператор - це поплавковий поділ, навіть якщо входи цілі.

>>> 20/15
1.33333333333

>>>20.0/15
1.33333333333

Для цілого поділу в Python 3 ми будемо використовувати //оператор.

//Оператор є оператором цілочисельного ділення як в Python 2.7 і Python 3.3.

У Python 2.7 та Python 3.3:

>>>20//15
1

Тепер дивіться порівняння

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

Для вищезгаданої програми вихід буде False в Python 2.7 та True у Python 3.3.

У Python 2.7 a = 1.75 та b = 1.

У Python 3.3 a = 1.75 та b = 1.75, тільки тому /, що це поділ поплавця.


8

Це стосується версії python, яку ви використовуєте. В основному він приймає поведінку C: якщо розділити два цілих числа, результати будуть округлені до цілого числа. Також пам’ятайте, що Python виконує операції зліва направо, що грає роль під час набору тексту.

Приклад: Оскільки це питання, яке завжди спливає в моїй голові, коли я роблю арифметичні операції (чи потрібно перетворювати в плаваюче і яке число), подається приклад з цього аспекту:

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

Коли ми ділимо цілі числа, не дивно, що вона стає нижчою округлою.

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

Якщо ми наберемо останнє ціле число для плавання, ми все одно отримаємо нуль, оскільки до того моменту, коли наше число ділиться на поплавок, вже стало 0 через ціле ділення.

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

Той самий сценарій, що і вище, але зміщення поплавкового типу наблизилось трохи ближче до лівого боку.

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

Нарешті, коли ми вводимо перше ціле число для плавання, результат є бажаним, оскільки починаючи з першого поділу, тобто лівого лівого, ми використовуємо поплавці.

Додатково 1: Якщо ви намагаєтесь відповісти на це, щоб поліпшити арифметичну оцінку, вам слід перевірити це

Додатково 2: Будьте уважні до наступного сценарію:

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

4

Визначення поплавця, розміщуючи "." після того, як число також призведе до плавання за замовчуванням.

>>> 1 / 2
0

>>> 1. / 2.
0.5

2

Зробіть принаймні один з них плаваючим, тоді це буде поплавковий поділ, а не ціле число:

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

Закидання результату плавати вже занадто пізно.


1

У python cv2не оновлено розрахунок поділу. Отже, ви повинні включити from __future__ import division в перший рядок програми.


0

У будь-якому випадку це ціле ділення. 10/90 = 0. У другому випадку ви просто кидаєте 0 на поплавок.

Спробуйте кинути один з операндів "/", щоб бути плавцем:

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

0

Ти кидаєш плисти після того, як поділ вже відбувся у твоєму другому прикладі. Спробуйте це:

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

0

Я дещо здивований, що ніхто не згадував, що оригінальний плакат, можливо, сподобався б раціональним цифрам. Якщо вас це зацікавить, програма Sage на базі Python має ваші спини . (Наразі все ще базується на Python 2.x, хоча 3.x триває.)

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

Це не є рішенням для всіх, оскільки воно робить деякі попередні підготовлення, тому ці числа не є int, а Integerелементами класу Sage . Все-таки варто згадати як частину екосистеми Python.


0

Особисто я вважав за краще вставити 1. *на самому початку. Тож вираз стає приблизно таким:

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

Як я завжди роблю поділ за такою формулою, як:

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

тому неможливо просто додати .0подібне 20.0. І в моєму випадку обгортання майном float()може втратити трохи читабельності.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.