2017-12-17 9 views
3

のpython3の範囲オブジェクトはO(1)封じ込めだから1は15 in range(3, 19, 2)を行うと、正しい答えにTrueなぜPython3のレンジ/スライスオブジェクトは、他のレンジ/スライスの包含テストをサポートしていませんか?

を得ることができ、整数(1)(2)

のチェックをサポートするしかし、それはW/B二つの範囲をチェック封じ込めをサポートしていません

a = range(0, 10) 
b = range(3, 7) 
a in b # False 
b in a # False, even though every element in b is also in a 
a < b # TypeError: '<' not supported between instances of 'range' and 'range' 

それはとして解釈さb in a範囲内の任意の要素「」等しいオブジェクトに「B」であると思われますか?

ただし、範囲には整数以外は使用できないため、range(...) in range(...)は常にFalseを返します。 IMHOでは、範囲 'a'の範囲 'b'のすべての要素はであるため、このようなクエリには回答する必要がありますか?この範囲には開始、終了、ステップ、および長さだけが格納されていると仮定すると、このクエリはO(1)でも応答できます。

スライスオブジェクトも役に立ちません。それは__contains__メソッドを実装していない、と(意味をなさない)__lt__方法単にcompares two slices as tuples

があり、これらの現在の実装の背後にある理由です、またはそれだけで「それがこの方法を実装するために起こった」ありますもの?

答えて

3

range_containsで、設定されたデータ構造を、使用することをお勧めします、ロングのための特別なケースと。

正しく表示されているように、e in bは、ebの要素である場合はtrueを返します。 ebのサブセットであるかどうかを確認するような他の実装はあいまいです。これはPythonでは特に問題があります。これは、iterablesが同種である必要はなく、ネストされたリスト/タプル/セット/イテラブルを許可します。

希望の動作が実装された世界を考えてみましょう。何をすべきele1 in my_listele2 in my_listリターン、この場合、

my_list = [1, 2, (3, 4), 5] 
ele1 = (3, 4) 
ele2 = (2, 5) 

:今、私たちは次のリストを持っていると仮定?

x = set([1]) 
y = set([1,2]) 
x < y # True 
[1] < y # raises a TypeError 
+0

範囲はコンテナではなく、整数範囲のみを表すシーケンスです。繰り返し可能ですが、そこから要素を削除することはできません。したがって、非数値型の包含を検査することは依然として可能です。しかし、あなたは正しいです、それは多くの混乱を招き、賛否両論は賛否を上回ります。 –

1

あなたは'b' containing 'a''a' being a subset of 'b'を混同しています。これらは2つの異なるものです。

b containing aを意味します。range(0, 10)は、bです。さんが言ってみましょう:

a = [1, 2, 3] 

b = [1, 2, 3, 4, 5] 

a in bは、実際のリスト[1, 2, 3][[1, 2, 3], 4, 5]である場合にのみ、真です。実際には、リスト自体が他のリストの中にあるかどうかをチェックしていますが、すべての要素が他のリストにあるわけではありません。

リストaは、すべてaのすべての要素がbの場合、bのサブセットです。あなたの例では、baのサブセットですが、実際のリストbは、aではありません。あなたはこのような方法をしたい場合は

、おそらくあなたが与えられた要素が反復可能である場合にだけチェックすることが範囲のため__contains__の実装のように見える

+2

これは、彼がすでに自分自身と言ったように聞こえます。 –

1
:ご希望の挙動がより安全、より良い方法は、現在の動作を維持することですな

if e in my_iterable: 
    # ah! e must exist! 
    my_iterable.remove(e) 

ようなコードを記述し、代わりにサブセット述語を実装するために、異なるタイプの敏感な演算子を使用することが面倒になり

Rangeオブジェクトはcollections.abc.Sequenceを実装し、包含テストをサポートします。

a in b 
b in a 

この場合、レンジオブジェクトaを範囲bで検索しています(逆も同様です)。それは間違っているはずです。

関連する問題