[Python] Setの積は元から定義されていた

昨日の 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 最高



Leave a comment


:

:

:

:

このエントリーのはてなブックマーク (-)