昨日の Rangeの積を求める なんですが, set のベースクラス BaseSet の定義を見てみたらこう書かれていました。
def __and__(self, other):
"""Return the intersection of two sets as a new set.
(I.e. all elements that are in both sets.)
"""
if not isinstance(other, BaseSet):
return NotImplemented
return self.intersection(other)
ということは,Set型は元から a & b という書き方ができるんですね。実際に試してみると,とても簡単に集合の積がとれました。
>>> a = range(1,7); b = range(3,10); c = range(4,12) >>> print a,b,c [1, 2, 3, 4, 5, 6] [3, 4, 5, 6, 7, 8, 9] [4, 5, 6, 7, 8, 9, 10, 11] >>> set(a) & set(b) set([3, 4, 5, 6]) >>> set(a) & set(b) & set(c) set([4, 5, 6])
終了──── しかも,RubyのRangeって数値以外も扱えるらしいじゃないですか。
全然だめだ>自分
気を取り直して,list型に「 & 」の振る舞いを実装してみることにします。元のlist型には「 & 」は定義されていないので,当然ながら「 a & b 」という表記はエラーになります。
>>> a = [1,2,3]; b = [2,3,4]; c = [3,4] >>> a & b Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for &: 'list' and 'list'
& 演算子は,__and__メソッドを定義することで利用可能になるので,新たに list を継承した xlist クラスを作ります。
class xlist(list):
def __and__(self, other):
return xlist(filter(lambda x: x in other, self))
実行してみましょう。
>>> a = xlist([1,2,3,4]); b = xlist([2,3,4,5]); c = xlist([4,5,6]) >>> a & b [2, 3, 4] >>> a & b & c [4]
できた。
り, Reduce 最高































