はじめに
pythonで文字列に対して部分文字列の検索を行うメソッドとして、str.findとstr.indexがあります。ほとんど同じものなのですが、どのような違いがあるのでしょうか?
str.findとstr.indexはどちらも文字列のメソッドで、引数に渡した文字列の位置を返します。
>>> "hoge".find("og") 1 >>> "hoge".index("og") 1
「一体なにが違うんだっけ」とふと思って調べてしまったので、メモします。
違い
大きな違いはありません。ヒットする場合はほとんど同じです。しかし、ヒットしなかった場合の挙動だけ異なります。
端的に言えばstr.findは見つからなかった場合-1を返しますが、str.indexは例外を送出します。
>>> "hoge".find("fuga") -1 >>> "hoge".index("fuga") Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: substring not found
str.index(sub[, start[, end]])(原文)
find() と同様ですが、部分文字列が見つからなかったとき ValueError を送出します。
それだけの違いのようです。単純ですね。
速度差
まさかこんなのに速度差なんてないだろう、そう思っていた時期が私にもありました。
>>> s = "hoge"*1000 + "fuga" >>> timeit.timeit(lambda : s.find("fuga")) 3.8523642780000955 >>> timeit.timeit(lambda : s.index("fuga")) 3.803682490000938
ヒットする場合は互角です。
>>> def f1(): ... ret = s.find("piyo") ... if ret == -1: ... pass ... else: ... pass ... >>> def f2(): ... try: ... ret = s.index("piyo") ... except: ... pass ... >>> timeit.timeit(f1) 3.907751840999481 >>> timeit.timeit(f2) 4.395755831001225
例外処理は単純な比較より重いため、少し時間を食うようです。なんてこった。
もちろん、処理目的にもよるため、「速いからfindの方が良い」とは一概には言えません。意図に応じて選ぶべきです。
ただ、例外処理を書くのは少し面倒だし、行数も増えるので、findの方が便利に使えるケースが多いかな?
まとめ
見つからなかったとき、str.findは-1を、str.indexはValueErrorを出すと覚えましょう。