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コメント:
コメントを投稿