in演算子、便利ですよね。こんな感じです。
a = [ 1, 2, 3 ] print 2 in a # True
C#なら、
var a = new int[] { 1, 2, 3 }; Console.WriteLine(a.Contains(2)); // True
ちょっとうっとうしい。C++に至っては、
int a[] = { 1, 2, 3 }; std::cout << (std::find(a, a + 3, 2) != a + 3) << std::endl; // 1
これですからね。
in演算子はこのようにsetや辞書やリストで使えますが、実はgenerator式などのiteratorでも使えるんですね。昨日気づきました。
g = (n * n for n in xrange(10)) print 9 in g # True
このあと、
print 16 in g # True print 4 in g # False
とすると、4はもう生成した後で、25, 36, …と生成されるのでFalseです。念のため、
g = (n * n for n in xrange(10)) print 23 in g # False
となります。
詳しくは、ドキュメントに書いてあります。__contains__()か__iter__()か__getitems__()が定義されていればin演算子が使えるんですね。iteratorには__iter__()メソッドがあるからin演算子が使えるわけです。__getitems__()についてもオレオレコンテナを作って試してみましょう。
class MyList: def __init__(self, a): self.a = a def __getitem__(self, k): return self.a[k] a = MyList([ 1, 3, 5 ]) print 2 in a # False print 3 in a # True
kを0から3までなめています。