1

range()との違いはよく知っていxrange()ます。私は何か奇妙なことに気づきましたxrange()

>>> xrange(1,10,2)
xrange(1, 11, 2)

>>> xrange(1,10,4)
xrange(1, 13, 4)

機能的には正しいです:

>>> for item in xrange(1,10,4):
...     print item
... 
1
5
9
>>>

ただし、ご覧のとおり、返さxrangeれるオブジェクトの停止値は、最後の有効な値の次に高い値です。理由は何ですか?

range()これで、Python2と同じ機能がPython3で提供xrangeされ、期待どおりに動作します。

>>> range(1,10,4)
range(1, 10, 4)
>>> range(1,10,2)
range(1, 10, 2)
>>> 
4

3 に答える 3

4

rangeまたはの停止値xrangeは常に排他的です。

ドキュメントからの引用(Python 2):

が正の場合step、最後の要素は;start + i * step 未満の最大の要素です。 stopが負の場合、最後の要素は。より大きいstep最小の要素です。start + i * step stop

そしてPython3の場合:

stepの場合、範囲rの内容は、式r[i] = start + step*iwherei >= 0および。によって決定されr[i] < stopます。

stepの場合でも、範囲の内容は式によって決定されますが、r[i] = start + step*i制約はとです。i >= 0r[i] > stop


に関する質問の2番目の部分repr()についてxrange

xrange(1, 10, 4)xrange(1, 13, 4)同一でありrepr()、ネイティブpythonオブジェクトの場合、通常、オブジェクトを再作成するための有効なpythonコードを返します。これは、最初にオブジェクトを作成したのとまったく同じPythonコードである必要はありません。

于 2013-03-14T12:49:45.247 に答える
3

xrange(1, 10, 4)と同等xrange(1, 13, 4)です。あなたの例を使用するには:

>>> for item in xrange(1,13,4):
...     print item
... 
1
5
9
>>> 

xrangePython 2では、start, stop, step引数を正規化します。内部的には、実装は、 start、step、およびstopの代わりにxrange、トリプルstart、step、およびlength(オブジェクト内の要素の数)を格納します。xrange実装方法xrange.__repr__()は次のとおりです[1]。

rtn = PyString_FromFormat("xrange(%ld, %ld, %ld)",
                          r->start,
                          r->start + r->len * r->step,
                          r->step);

[1] https://github.com/replit/empythoned/blob/master/cpython/Objects/rangeobject.c

于 2013-03-14T13:00:41.733 に答える
2

それは本当に問題ですか?

効果は同じです。の出力には 10 も 11 も含まれずxrange()xrange(1, 11, 2)同等ですxrange(1, 10, 2)

Python 2 範囲型 ( の結果xrange()) は、終了値ではなく範囲の長さを格納するため、repr出力を作成するために、その終了値が計算されます。また、ステップ値を使用したため、計算では数式の結果が表示されますstart + length * step。実装にとって、長さはより重要な値であり、end値は安全に破棄でき、必要に応じて再計算できます。

したがって、 を作成すると、範囲の長さが計算され、終了値の代わりにそれがxrange(1, 10, 2)格納されます。

if (step > 0 && lo < hi)
return 1UL + (hi - 1UL - lo) / step;
else if (step < 0 && lo > hi)
return 1UL + (lo - 1UL - hi) / (0UL - step);
else
return 0UL;

Python 3 Range オブジェクトは、長さに加えて終了値を格納するため、オブジェクトに対してクエリを実行し、repr出力に表示できます。

于 2013-03-14T12:56:41.273 に答える