Pythonのoperatorモジュールの使い方(itemgetterなど)

Modified: | Tags: Python

Pythonの標準ライブラリのoperatorモジュールでは、+<などの演算子に対応する関数や、オブジェクトの要素・属性を取得したりメソッドを実行したりする呼び出し可能オブジェクトを生成する関数が提供されている。

呼び出し可能オブジェクトを指定する引数にoperatorの関数を使うと、シンプルに書けたり、より高速に処理できたりする。

operator.itemgetter(), attrgetter(), methodcaller()sorted()関数などの引数keyに使われることが多い。具体例などの詳細は以下の記事を参照。

組み込み演算子に対応するoperatorモジュールの関数

operatorモジュールでは組み込み演算子に対応する関数が提供されている。

ここでは代表的なものをいくつか紹介する。本記事で扱っていないものもあるので、一覧は以下の公式ドキュメントの対応表を参照されたい。

算術演算子

Pythonには+*などの算術演算子がある。

例えば+演算子はoperator.add()で実現できる。a + boperator.add(a, b)と等価。

import operator

print(2 + 3)
# 5

print(operator.add(2, 3))
# 5

そのほか、-, *, /, //演算子に対応する関数も提供されている。

print(operator.sub(2, 3))  # 2 - 3
# -1

print(operator.mul(2, 3))  # 2 * 3
# 6

print(operator.truediv(2, 3))  # 2 / 3
# 0.6666666666666666

print(operator.floordiv(2, 3))  # 2 // 3
# 0

比較演算子

<==などの比較演算子に対応する関数も提供されている。

print(operator.lt(2, 3))  # 2 < 3
# True

print(operator.le(2, 3))  # 2 <= 3
# True

print(operator.gt(2, 3))  # 2 > 3
# False

print(operator.ge(2, 3))  # 2 >= 3
# False

print(operator.eq(2, 3))  # 2 == 3
# False

print(operator.ne(2, 3))  # 2 != 3
# True

論理演算子

ビット単位の論理演算子である&(AND)や|(OR), ^(XOR)などに対応する関数も提供されている。

ここでは0bを使って整数intを2進数で表し、結果をbin()で2進数に変換して出力している。

print(bin(0b1100 & 0b1010))
# 0b1000

print(bin(operator.and_(0b1100, 0b1010)))
# 0b1000

print(bin(0b1100 | 0b1010))
# 0b1110

print(bin(operator.or_(0b1100, 0b1010)))
# 0b1110

print(bin(0b1100 ^ 0b1010))
# 0b110

print(bin(operator.xor(0b1100, 0b1010)))
# 0b110

そのほか、~(反転)やビットシフト<<, >>に対応する関数もある。

なお、operator.and_()operator.or_()という名前だが、ブール演算子のandorとは違うので注意。

print(bin(0b1100 and 0b1010))
# 0b1010

print(bin(0b1100 or 0b1010))
# 0b1100

andorでは左右のオブジェクトを真か偽か判定した上で、左か右のいずれかの値が返されるので上のような結果となる。詳細は以下の記事を参照。

Python3.11時点ではandorに対応する関数は提供されていない。

オブジェクトの要素を取得: operator.itemgetter()

operator.itemgetter()は対象となるオブジェクトの要素を取得する呼び出し可能オブジェクトを生成する。

[]を使ったインデックス指定などに相当する処理を実行できる。

l = [0, 10, 20, 30, 40, 50]

print(l[3])
# 30

f = operator.itemgetter(3)
print(f(l))
# 30

operator.add()などとは異なり、operator.itemgetter()が生成するのは呼び出し可能オブジェクト。さらに対象を括弧()で指定して呼び出すことで実行される。

()が連続して奇妙に感じるかもしれないが、続けて書くと以下のようになる。

print(operator.itemgetter(3)(l))
# 30

以降、動作を紹介するために()を連続した書き方を用いる場合がある。

通常の[]によるインデックス指定と同じく、負の値で後ろからの位置で指定することも可能。

print(l[-1])
# 50

print(operator.itemgetter(-1)(l))
# 50

スライスにも対応している。slice()関数を利用する。

print(l[1:4])
# [10, 20, 30]

print(operator.itemgetter(slice(1, 4))(l))
# [10, 20, 30]

print(l[1::2])
# [10, 30, 50]

print(operator.itemgetter(slice(1, None, 2))(l))
# [10, 30, 50]

operator.itemgetter()の引数には複数の値を指定可能。それぞれの結果を要素とするタプルが返される。

print(operator.itemgetter(0, slice(1, 4), -1)(l))
# (0, [10, 20, 30], 50)

print(type(operator.itemgetter(0, slice(1, 4), -1)(l)))
# <class 'tuple'>

operator.itemgetter()__getitem__()によってアイテムを取得している。リストやタプルなどのインデックス指定だけでなく、辞書dictのキー指定による値取得などにも対応している。

d = {'k1': 0, 'k2': 10, 'k3': 20}

print(d['k2'])
# 10

print(operator.itemgetter('k2')(d))
# 10

print(operator.itemgetter('k2', 'k1')(d))
# (10, 0)

operator.itemgetter()の具体的な利用例として、sorted()関数などの引数keyへの指定がある。詳細は以下の記事を参照。

オブジェクトの属性を取得: operator.attrgetter()

operator.attrgetter()は対象となるオブジェクトの属性を取得する呼び出し可能オブジェクトを生成する。

.xxxのような属性取得に相当する処理を実行できる。

日付情報を保持するdatetime.dateオブジェクトを例とする。

import datetime

dt = datetime.date(2001, 10, 20)
print(dt)
# 2001-10-20

print(type(dt))
# <class 'datetime.date'>

print(dt.year)
# 2001

operator.attrgetter()で属性を取得する呼び出し可能オブジェクトを生成できる。operator.itemgetter()と同様、複数の属性をまとめて取得可能。

f = operator.attrgetter('year')
print(f(dt))
# 2001

print(operator.attrgetter('year', 'month', 'day')(dt))
# (2001, 10, 20)

オブジェクトのメソッドを実行: operator.methodcaller()

operator.methodcaller()は対象となるオブジェクトのメソッドを実行する呼び出し可能オブジェクトを生成する。

s = 'xxxAyyyAzzz'

print(s.upper())
# XXXAYYYAZZZ

f = operator.methodcaller('upper')
print(f(s))
# XXXAYYYAZZZ

引数も指定可能。キーワード引数も指定できる。

print(s.split('A', maxsplit=1))
# ['xxx', 'yyyAzzz']

print(operator.methodcaller('split', 'A', maxsplit=1)(s))
# ['xxx', 'yyyAzzz']

operator.attrgetter()operator.methodcaller()operator.itemgetter()と同じくsorted()関数などの引数keyへの指定に利用されることがある。

関連カテゴリー

関連記事