2010-06-02 2 views
103

Я пытался нормализовать набор чисел от -100 до 0 до диапазона 10-100 и имел проблемы только для того, чтобы заметить, что даже без каких-либо переменных это не оценивает способ, который я ожидал бы это:Python division

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

Float разделение не работает либо:

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

Если какая-либо сторона разделения отливают поплавка он будет работать:

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

Каждая сторона в первом примере оценивается как int, что означает, что окончательный ответ будет передан в int. Поскольку 0.111 меньше, чем 0,5, он округляется до 0. Это, по-моему, непрозрачно, но я думаю, что так оно и есть.

Какое объяснение?

+1

См. Также: [Почему это подразделение не работает в python?] (Http://stackoverflow.com/questions/1787249/why-doesnt-this-division-work-in-python/1787255#1787255) – miku

+1

Адам, мне все еще не нравятся ваши объяснения. Первый пример - целочисленное деление, которое просто возвращает 0. Второй пример ошибочно заключен в скобки для желаемого эффекта. –

+0

@GregS Первым примером была проблема. Второй пример пояснительный и был написан после первого вопроса. Все ответы ниже объясняют проблему очень хорошо, особенно @KennyTM. Важно отметить, что моя первоначальная проблема - это только проблема на Python 2.x, а не 3. Это немного смущает, что поведение изменится так, но теперь, когда я знаю, я буду использовать из __future__ import division и использовать 3 .x. Приветствия. –

ответ

206

Вы используете 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 
+9

Если вы используете 'из __future__ import division', вы можете получить старое поведение деления C-стиля с помощью двух косых черт (например,' 1 // 2' приведет к 0). См. [Pep 238 Изменение оператора отдела] (http://www.python.org/dev/peps/pep-0238/) – User

+0

Работает ли оператор '//' в Python 2.x? – sam

+0

@sam: см. Комментарий пользователя выше. – kennytm

10

Вам нужно сменить его на поплавок, прежде чем выполнять деление. То есть:

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

@ Адам Нельсон: Работает правильно для меня. Проверьте скобки. –

+0

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

+10

@ Адам: Неважно, с какой стороны сначала. – kennytm

0

В любом случае, это целочисленное деление. 10/90 = 0. Во втором случае вы просто бросаете 0 в поплавок.

Попробуйте литье один из операндов «/», чтобы быть поплавок:

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

Вы литья плавать после того, как подразделение уже произошло в вашем втором примере. Попробуйте это:

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

Я узнал, что python имеет преобразования, а не отбрасывает. – miku

17

Вы putting Integers in so Python is giving you an integer back:

>>> 10/90 
0 

Если при разыгрывании этого поплавка после округления будет уже сделано, другими словами, 0 целого число всегда становится 0 поплавком ,

Если вы используете поплавки по обе стороны от деления, то Python даст вам ответ, который вы ожидаете.

>>> 10/90.0 
0.1111111111111111 

Так что в вашем случае:

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

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

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

Кастинг результат плавать слишком поздно.

2

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

>>> 1/2 
0 

>>> 1./2. 
0.5 
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 

Наконец, когда мы первое приведение целое число с плавающей точкой, результатом является искомой, так как начиная с первого деления, то есть самый левый один, мы используем поплавки.

Extra 1: Если вы пытаетесь ответить, что для улучшения арифметической оценки, вы должны проверить this

Extra 2: Пожалуйста, обратите внимание следующий сценария:

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

В 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 

Для указанной программы, то выход будет Ложные в Python 2.7 и Истинного в Python 3.3.

В Python 2.7 а = 1,75 и б = 1.

В Python 3.3 а = 1,75 и б = 1.75, только потому, что / - это плавающее подразделение.

+1

Спасибо за ваш ответ. Это сэкономило мне много времени. – Jorge

0

Я несколько удивлен, что никто не упомянул, что оригинал плаката, возможно, понравился рациональных номеров. Если вас это интересует, программа на основе Python Sage has your back. (В настоящее время по-прежнему базируется на Python 2.x, 3.x, хотя идет полным ходом.)

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

Это не решение для всех, потому что это действительно сделать некоторые preparsing так что эти цифры не являются int s, но Sage Integer элементов класса. Тем не менее, стоит упомянуть как часть экосистемы Python.

0

Лично я предпочел вставить 1. * в самом начале. Таким образом, выражение стало чем-то вроде этого:

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

Как я всегда делаю разделения для некоторой формулы, как:

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

так нельзя просто добавить .0 как 20.0. И в моем случае упаковка с float() может потерять немного читаемость.