Python, версия 3.5

У меня есть следующий код:

def drange(start, stop, step):
    r = start
    while r < stop:
        yield r
        r += step

def my_func():
    whole_nums = [float(num) for num in range(0, 100)]
    for x in drange(0.0, 100.01, 0.01):
        if str(x).split('.')[1] == '0':
            x = str(x).split('.')[0]
        else:
            x = round(x, 2)
        print(str(x))
        time.sleep(0.2)

Функция drange проходит по заданным числам с заданным приращением и возвращает числа. Проблема в том, что я хочу 0, 1, 2, 3 и т. Д., Но это даст 0,0, 1,0 и т. Д.

Я подумал, что, поскольку я знал формат этих неправильных чисел (все другие числа между 0, например, до 99,99, я хочу), я мог просто сделать:

str(theNumber).split('.')[1]

(как видно из my_func), и если бы вывод был '0', то я знал бы, что у меня есть 0.0, 1.0 и т. д. и мог бы получить желаемый результат с помощью str(theNumber).split('.')[0] и, конечно, преобразовать его в Int или что-то еще.

Но! Когда я выполняю my_func, то решение .split() работает только на 0.0, когда оно достигает 1.0, оно просто пропускает оператор if и переходит в else, выводя вместо него 1.0 из 1.

Код должен работать нормально, ничего не импортируя, поэтому не стесняйтесь.

Обновить

Хорошо, похоже, мой подход в корне ошибочен (см. Ответ @danils), поэтому мой вопрос сейчас: как я могу генерировать числа в диапазоне от 0 до 100 с шагом 0,01, при этом обеспечивая целые числа целыми. так

0, 0.01, ..., 1, 1.01, 1.1, 1.02, ... 99.5, 99.51, ..., 100

1
7013145 27 Авг 2017 в 11:37

3 ответа

Лучший ответ

Вы никогда не должны полагаться на строковое представление целых чисел с плавающей точкой, потому что они редко имеют точное представление (приближения приводят к погрешностям точности, которые бросают гаечные ключи в работах).

Вам не нужно str(x) для print, потому что print автоматически сделает это за вас.

Более того, кажется, что ваша функция drange вносит неточности с плавающей запятой при генерации следующих значений в шаге. Вместо этого вы можете использовать np.arange для диапазона, он поддерживает десятичные шаги:

import numpy as np
out = np.arange(0.0, 100.01, 0.01)
print(out)

array([  0.00000000e+00,   1.00000000e-02,   2.00000000e-02, ...,
         9.99800000e+01,   9.99900000e+01,   1.00000000e+02])

Примечание. Если у вас нет numpy, вы можете установить его, используя pip install numpy.

И наконец, вы можете использовать float.is_integer, чтобы проверить, является ли число с плавающей точкой целым числом.


for x in np.arange(0.0, 100.01, 0.01):
    if x.is_integer():
        x = int(x)
    else:
        x = round(x, 2)

    print(x)

Это дает вам:

0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
...
2
cs95 27 Авг 2017 в 08:55

Для версии, не включающей numpy:

import time

def drange(start, stop, step):
    r = start
    while r < stop:
        yield r
        r += step

def my_func():
    whole_nums = [float(num) for num in range(0, 100)]
    for x in drange(0.0, 100.01, 0.01):
        x = float(int(x * 100))/100
        if x.is_integer():
            print(int(x))
        else:
            print (x)
        time.sleep(0.01)

if __name__ == "__main__":
    my_func()

По общему признанию, усекающая функция является сырной.

0
Hack Saw 27 Авг 2017 в 09:17

Это из-за арифметики с плавающей точкой. Это не совсем 1.0 то, что вы получаете, больше похоже на 1.0000000000000007. Итак, str(x).split('.')[1] == '0000000000000007'.

> import numpy as np
> np.arange(0.0, 100.0, 0.1)
array([   0. ,    0.1,    0.2, ...,   99.8,   99.9,  100. ])
0
Danil Speransky 27 Авг 2017 в 08:55