1. 関数 reduce と sum を使い合計を求める
Python の組み込み関数 reduce を使うと、リスト要素の合計を求めることができる。
a = [1, 5, 8, 12] print reduce(lambda x,y: x+y, a)
合計を求めるには、もっと簡単な方法として、組み込み関数 sum がある。
2.1 組み込み関数 によると、
sum( sequence[, start])
start と sequence の要素を左から右へ加算してゆき、総和を返します。start はデフォルトで 0です。 sequence の要素は通常は数値で、文字列であってはなりません。文字列からなるシーケンスを結合する高速かつ正しい方法は''.join(sequence)です。sum(range(n), m)はreduce(operator.add, range(n), m)と同等です。 バージョン 2.3 で 新たに追加 された仕様です。
実は、sum 関数があることを忘れて、reduce 関数で合計を求めていたことがある。 ^^;
で一度動作を確認しているはずなのになぁ…。
2. 加算の演算子を表す operator.add
上記で引用した、組み込み関数 sum の説明には、sum を実装するために reduce を利用して、
reduce(operator.add, range(n), m)
と記述されている。
operator.add
とは、何のことだろう?
6.7 operator -- 関数形式の標準演算子 によると、
operator モジュールは、Python 固有の各演算子に対応している C 言語で実装された関数セットを提供します。例えば、
operator.add(x, y)は式x+yと等価です。関数名は特殊なクラスメソッドとして扱われます; (...)これらの関数はそれぞれ、オブジェクトの比較、論理演算、数学演算、シーケンス操作、および抽象型テストに分類されます。
つまり、Python では、Haskell のように関数の引数として、組み込みの演算子
(+)
を渡すことができない。その代わり、operator モジュールの operator.add で代用する。
3. operator モジュールのメソッドをクラスで定義する
operator モジュールにあるメソッドをクラスに定義すると、オブジェクトに対して、組み込みの演算子を用いることができる。
例えば、
__add__(a, b) メソッド
をクラスに定義すると、オブジェクトに対して + 演算子を適用できる。
例えば、
「太郎、21歳」と「花子、15 歳」を足した結果、二人の年齢を足した「名無しの Person オブジェクト」を返す
という仕様を想定する。 「Python のイテレータ」 で定義した Person クラスを使い、試してみる。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.name + " " + str(self.age)
def __cmp__(self, other):
result = cmp(self.age, other.age)
if result == 0:
return cmp(self.name, other.name)
else:
return result
def __add__(a, b):
return Person("", a.age + b.age)
persons = [Person("Tarou", 21), Person("Hanako", 15), Person("Jiro", 15)]
total = Person("", 0)
for person in persons:
total += person
print total.age
print reduce(lambda x,y: x+y, persons).age
# sum における初期値を設定する。初期値は数値の 0 であることに注意。
print sum(persons, Person("", 0)).age
結果は、
51 51 51
4. __XXXXXX_ 系のメソッドはどこに宣言してある?
上記のような関数を見ると、組み込み関数についてしっかりと押さえ、
__XXXXX__ 系
の特殊なメソッドを覚える必要があると感じる。
標準型の階層を手がかりに、Python の中に入っていけるようにならないとダメかなぁ。 (+_+)
それにしても、__XXXXX__ は、どこクラスに宣言されているのだろう?
0コメント:
コメントを投稿