Подтвердить что ты не робот

Переменный шаг в цикле for

Я пытаюсь установить петлю между 0,01 и 10, но между 0,01 и 0,1 используют 0,01 в качестве шага, затем между 0,1 и 1,0 используют 0,1 в качестве шага и от 1,0 до 10,0 используют в качестве шага 1,0.

Я написал код цикла while, но хочу сделать его более питоническим.

i = 0.01
while i < 10:
   # do something
   print i
   if i < 0.1:
       i += 0.01
   elif i < 1.0:
       i += 0.1
   else:
       i += 1

Это приведет к созданию

0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 4, 5, 6, 7, 8, 9
4b9b3361

Ответ 1

Функция генератора специального кошелька может быть правильным способом. Это эффективно отделяет скучную часть (получая список цифр справа) от интересной части (# do something в вашем примере).

def my_range():
    for j in .01, .1, 1.:
        for i in range(1, 10, 1):
            yield i * j

for x in my_range():
    print x

Ответ 2

У вас может быть вложенный цикл, внешний, который выполняет итерацию над точностью и внутренней, которая просто range(1,10):

for precision in (0.01, 0.1, 1):
    for i in range(1,10):
        i*=precision
        print(i)

Однако поплавки, вероятно, не будут работать в этом случае, так как это показывает значения, такие как 0.30000000000000004 на моей машине, для точных десятичных значений вы хотели бы использовать decimal:

import decimal
for precision in ("0.01", "0.1", "1"):
    for i in range(1,10):
        i*=decimal.Decimal(precision)
        print(i)

Ответ 3

Один подход состоял бы в использовании двух циклов: один для порядка величины и один для значений от 1 до 9:

for exp in range(-2, 1):
    for i in range(1, 10):
        print("{:.2f}".format(i * 10 ** exp))

Ответ 4

Просто одна строка кода через понимание списка -

for k in [i*j for j in (0.01, 0.1, 1) for i in range(1, 10)]

Не может быть больше pythonic!

Ответ 5

Я бы рекомендовал функцию генератора, но если шаги не являются такими удобными друг другу, я бы написал это как

def my_range():
    i = 0
    while i < 0.1:
        i += 0.01
        yield i
    while i < 1:
        i += 0.1
        yield i
    while i < 10:
        i += 1
        yield i

for x in my_range():
    print x

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

Если он становится слишком повторяющимся, используйте

def my_range():
    i = 0
    for (end, step) in [(0.1, 0.01), (1, 0.1), (10, 1)]:
        while i < end:
            i += step
            yield i

Ответ 6

Вы можете сделать что-то вроде:

import numpy as np
list1 = np.arange(0.01, 0.1, 0.01)
list2 = np.arange(0.1, 1, 0.1)
list3 = np.arange(1, 10, 1)
i_list = np.concatenate((list1, list2, list3))  # note the double parenthesis
for i in i_list:
    ...

В основном вы создаете весь список значений, которые вам нужны спереди, i_list, а затем просто повторяйте их в цикле for.

Ответ 7

На всякий случай вы хотели бы заменить цикл кодом векторизованным...

In [63]: np.ravel(10.**np.arange(-2, 1)[:,None] * np.arange(1, 10)[None,:])
Out[64]: 
array([ 0.01,  0.02,  0.03,  0.04,  0.05,  0.06,  0.07,  0.08,  0.09,
        0.1 ,  0.2 ,  0.3 ,  0.4 ,  0.5 ,  0.6 ,  0.7 ,  0.8 ,  0.9 ,
        1.  ,  2.  ,  3.  ,  4.  ,  5.  ,  6.  ,  7.  ,  8.  ,  9.  ])