ドキュメント は基本的に、range
がこの実装とまったく同じように動作する必要があることを示しています(正のstep
の場合):
def range(start, stop, step):
x = start
while True:
if x >= stop: return
yield x
x += step
また、引数は整数でなければならないとも述べています。何故ですか?ステップがフロートの場合、その定義も完全に有効ではありませんか?
私の場合、私はespです。 range
引数としてfloat型を受け入れるstep
関数が必要です。 Pythonにありますか、自分で実装する必要がありますか?
より具体的には、このCコードをPythonにナイスな方法で直接変換するにはどうすればよいですか(つまり、手動でwhile
- loopを介して行うだけではありません):
for(float x = 0; x < 10; x += 0.5f) { /* ... */ }
編集:ドキュメントは numpy.linspace
。 気づいてくれてありがとう@Droogans =)
1つの説明は、浮動小数点の丸めの問題かもしれません。たとえば、あなたが呼び出すことができる場合
range(0, 0.4, 0.1)
あなたはの出力を期待するかもしれません
[0, 0.1, 0.2, 0.3]
しかし、あなたは実際に次のようなものを得ます
[0, 0.1, 0.2000000001, 0.3000000001]
丸めの問題が原因です。また、範囲は何らかのインデックスの生成によく使用されるため、整数のみです。
それでも、フロート用の範囲ジェネレーターが必要な場合は、独自のものをロールバックできます。
def xfrange(start, stop, step):
i = 0
while start + i * step < stop:
yield start + i * step
i += 1
範囲式で小数を使用できるようにするためのクールな方法は、次のとおりです。[x * range for x in range(0、10)]
浮動小数点の問題は、不正確なために、期待した数のアイテムを取得できない可能性があることです。アイテムの正確な数が非常に重要な多項式で遊んでいる場合、これは実際の問題になる可能性があります。
本当に必要なのは算術的進行です。次のコードは、int
、float
およびcomplex
...および文字列、リスト...
def arithmetic_progression(start, step, length):
for i in xrange(length):
yield start + i * step
このコードは、現在の合計を維持する他の選択肢よりも、最後の値が期待値の雄牛のwithin音内にある可能性が高いことに注意してください。
>>> 10000 * 0.0001, sum(0.0001 for i in xrange(10000))
(1.0, 0.9999999999999062)
>>> 10000 * (1/3.), sum(1/3. for i in xrange(10000))
(3333.333333333333, 3333.3333333337314)
訂正:ここに 競合するランニングトータルガジェット :
def kahan_range(start, stop, step):
assert step > 0.0
total = start
compo = 0.0
while total < stop:
yield total
y = step - compo
temp = total + y
compo = (temp - total) - y
total = temp
>>> list(kahan_range(0, 1, 0.0001))[-1]
0.9999
>>> list(kahan_range(0, 3333.3334, 1/3.))[-1]
3333.333333333333
>>>
浮動小数点数を一緒に追加すると、しばしば少しのエラーが発生します。 range(0.0, 2.2, 1.1)
は[0.0, 1.1]
または[0.0, 1.1, 2.199999999]
を返しますか?厳密な分析なしに確実な方法はありません。
本当に必要な場合は、投稿したコードは回避策です。考えられる欠点に注意してください。
十分な特殊なケースを次に示します。
[ (1.0/divStep)*x for x in range(start*divStep, stop*divStep)]
あなたの場合、これは次のようになります:
#for(float x = 0; x < 10; x += 0.5f) { /* ... */ } ==>
start = 0
stop = 10
divstep = 1/.5 = 2 #This needs to be int, thats why I said 'special case'
など:
>>> [ .5*x for x in range(0*2, 10*2)]
[0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5]
これは私が使用するものです:
numbers = [float(x)/10 for x in range(10)]
のではなく:
numbers = [x*0.1 for x in range(10)]
that would return :
[0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9]
それが役に立てば幸い。