2016-06-15 5 views
19

0.01から10の間でループしようとしていますが、0.01と0.1の間で0.01をステップとして使用し、0.1と1.0の間で0.1をステップとして使用し、1.0と10.0の間で1.0をステップとして使用します。forループの可変ステップ

私はwhileループコードを書いていますが、もっとpythonicしたいです。

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 
+3

を使用するには、関数の中で、ループの最後の命令として '降伏i'を追加することを置きます。これはジェネレータになります。 – njzk2

+6

浮動小数点丸めの制約では、ステップごとにインクリメントすることはうまく機能しません。あなたは境界エラーを持つ可能性が高いです。 – user2357112

+1

@ njzk2 - 'yield 'は、ループの最初の**命令でなければなりません。彼の最初の価値は '.01'である必要があります。 –

答えて

3

あなたは、ネストされたループを持っている可能性がちょうどrange(1,10)精度と内側の1を反復処理である外側のものが生成されます:山車があるしかし

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

私のマシン上に0.30000000000000004のような値が表示されているので、この場合はおそらく動作しません。正確な10進値の場合は、decimal m odule:大きさの順序のための1つ、および1から9までの値のための1つ:

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

ええ、今でもあまりにも、私の頭はちょうどそれには今日ありません。 –

3

一つのアプローチは、2つのループを使用することであろう

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

特殊財布生成機能であるかもしれません行く正しい道。これは、面白い部分(あなたの例では# 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 
+0

これは主に動作します。あなたは '' 0.30000000000000004'のような奇妙な結果を得ます。 –

+1

もちろん。これが浮動小数点演算の性質です。 '0.3 'は' float'では表現できません。 –

+1

ええ、私の驚きはありません。私はこのOPのコメントをしました。 –

1

あなたのような何かを行うことができます:基本的にはあなたがちょうどあなたのforループでそれらを反復処理、i_list、あなたがアップフロント必要な値の全リストを作成

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: 
    ... 

を。

3

リスト内包によるコードの1行だけ -

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

より神託することはできません!ちょうどあなたがベクトル化コードでループを置き換えることを望んだ場合

+3

割り当ては必要ありません。 OPはループを駆動するためにこれを使用したい:範囲(1,10)内のiのためのx in(i * j in(.01、.1,1)):print x' –

+1

うん、ちょうどいいそれを固定した。 – hashcode55

+0

:(単なる行に3つの 'for'文があるように思えたのですが)私はそれを他の方法でやったほうがいいです。 –

1

...

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. ]) 
+2

Numpyはこの問題のために残酷です。 – Mego

+0

はい、数値を表示するには(ここでは、私がここで提案したNumPyベースの唯一の解決法ではありません)、しかし、 ''#do something''ブロックには時間のかかる関数への呼び出しが含まれます。 – Tonechas

2

私は同様に発電機能をお勧めしますが、手順は、互いの、このような便利な累乗でない場合私は、それはもう少し繰り返しかもしれません

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 
+0

他の代入と同様に、 '+ ='代入はPythonのステートメントであり、あなたは 'それらを収穫します。 – user2357112

+0

@ user2357112:右は修正されました。 – Bergi