Python 3で異なる値で初期化された範囲が互いに等しいのはなぜですか?
インタープリターで次のコマンドを実行すると:
>>> r1 = range(0)
>>> r2 = range(2, 2, 2)
>>> r1 == r2
True
結果はTrue
です。これはなぜですか?異なるパラメーター値を持つ2つの異なるrange
オブジェクトが等しいものとして扱われるのはなぜですか?
ドキュメント (エンファシス鉱山)からの直接引用:
==および!=を使用して範囲オブジェクトが等しいかどうかをテストすると、それらがシーケンスとして比較されます。つまり、2つの範囲オブジェクトは、値の同じシーケンスを表す場合、等しいと見なされます。 (等しいことを比較する2つの範囲オブジェクトは、start、stop、step属性が異なる場合があることに注意してください。たとえば、range(0)== range(2、1、3)またはrange(0、3、2)== range(0、 4、2)。)
range
sを「同じ」リストと比較すると、 ドキュメント にも記載されているように、不等式になります。
異なる数値型を除く異なる型のオブジェクトは、等しく比較されません。
例:
_>>> type(range(1))
<class 'range'>
>>> type([0])
<class 'list'>
>>> [0] == range(1)
False
>>> [0] == list(range(1))
True
_
これは明示的にPython 3.にのみ適用されることに注意してください。Python 2では、range
はリストを返すだけで、range(1) == [0]
はTrue
として評価されます。
このページの優れた回答にいくつかの詳細を追加するために、2つのrange
オブジェクト_r0
_と_r1
_が比較されます おおよそ次のように :
_if r0 is r1: # True if r0 and r1 are same object in memory
return True
if len(r0) != len(r1): # False if different number of elements in sequences
return False
if not len(r0): # True if r0 has no elements
return True
if r0.start != r1.start: # False if r0 and r1 have different start values
return False
if len(r0) == 1: # True if r0 has just one element
return True
return r0.step == r1.step # if we made it this far, compare step of r0 and r1
_
range
オブジェクトの長さは、start
、stop
、およびstep
パラメーターを使用して簡単に計算できます。たとえば、_start == stop
_の場合、Pythonは、長さが0であることをすぐに知ることができます。自明でない場合、Python start
、stop
、およびstep
の値を使用して 単純な算術計算 を実行します。
したがって、range(0) == range(2, 2, 2)
の場合、Pythonは次のことを行います。
range(0)
とrange(2, 2, 2)
はメモリ内の異なるオブジェクトであることがわかります。start == stop
_であるため)であるため、別のテストが必要です。len(range(0))
が0であることがわかります。これは、len(range(2, 2, 2))
も0(以前の不等式のテストが失敗した)であるため、比較がTrue
を返すことを意味します。res = range(0) == range(2, 2, 2)
どこで:
range(0)
0
から0
-0
ステップの範囲(ここでstep
はデフォルト値1
に等しい)、値なしのリストを意味します。
range(2, 2, 2)
は、2
から2
までの範囲を意味し、ステップは2
に等しく、値なしのリストです。
だから、これらの範囲は本当に等しい
range(0)
はrange(0,0)
を返します。ステップ1で0から0まで開始します。3番目の引数は0(デフォルト)にできないため、未定義です。 1で0に到達することはできません。カウンターのアクションがないため、0です。
range(2, 2, 2)
はrange(2, 2, 2)
を返します。 2から2まで開始しますが、2のステップで開始します。ここでも、何にもカウントされないため、基本的に0です。
range(0) == range(2,2,2)
Trueとexactlyは同じです。