1

私はいくつかのアプローチを試しましたが、正確さではなく、パフォーマンスのみに関心があります。正規表現ベースの実装は、型強制を使用する実装よりも約 3 ~ 4 倍遅いことに気付きました。これを行う別のより効率的な方法はありますか?

def IsNumber(x):
    try:
        _ = float(x)
    except ValueError:
        return False
    return True

 def IsNumber2(x):
     import re
     if re.match("^\d*.?\d*$", x) == None:
         return False
     return True

ありがとう!

4

4 に答える 4

6

まず第一に、彼らは同じことをしていません。たとえば、float は "1e3" として指定でき、float() はそれを受け入れます。それも強制ではなく、回心です。

次に、特に timeit で使用しようとしている場合は、IsNumber2 に re をインポートしないでください。関数の外でインポートを行います。

最後に、float() の方が高速であることは驚くことではありません。これは、非常に特定の目的のために C で記述された専用のルーチンですが、正規表現は解釈される形式に変換する必要があります。

float() を使用する最初のバージョンは十分に高速ですか? そうあるべきであり、Python で同じことを行うより良い方法を私は知りません。

于 2010-02-11T22:24:26.317 に答える
2

あまり。強制はこれを行うための受け入れられた方法です。

于 2010-02-11T22:20:16.793 に答える
2

答えは、「数値文字列」の意味に大きく依存します。数値文字列の定義が「float が受け入れるものすべて」である場合、try-except メソッドを改善することは困難です。

ただし、float は必要以上にリベラルである可能性があることに注意してください。ほとんどのマシンでは、無限大と nan を表す文字列を受け入れます。'nan(dead!$#parrot)'私のマシンでは、たとえば受け入れます。また、先頭と末尾の空白も受け入れます。アプリケーションによっては、float の指数表現を除外したい場合があります。このような場合、正規表現を使用することは理にかなっています。無限大と nan のみを除外するには、try-except メソッドを使用してから、math.isnan と math.isinf を使用して変換の結果を確認する方が速い場合があります。

数値文字列の正しい正規表現を作成することは、驚くほどエラーが発生しやすい作業です。たとえば、IsNumber2関数は string を受け入れます'.'。decimal モジュールのソースで、数値文字列の正規表現の実戦でテストされたバージョンを見つけることができます。これは次のとおりです(いくつかのマイナーな編集が​​あります):

_parser = re.compile(r"""        # A numeric string consists of:
    (?P<sign>[-+])?              # an optional sign, followed by either...
    (
        (?=\d|\.\d)              # ...a number (with at least one digit)
        (?P<int>\d*)             # having a (possibly empty) integer part
        (\.(?P<frac>\d*))?       # followed by an optional fractional part
        (E(?P<exp>[-+]?\d+))?    # followed by an optional exponent, or...
    |
        Inf(inity)?              # ...an infinity, or...
    |
        (?P<signal>s)?           # ...an (optionally signaling)
        NaN                      # NaN
        (?P<diag>\d*)            # with (possibly empty) diagnostic info.
    )
    \Z
""", re.VERBOSE | re.IGNORECASE | re.UNICODE).match

これは float が受け入れるものとほとんど一致しますが、先頭と末尾の空白と nan のわずかな違い (nan を通知するための余分な 's' と診断情報) を除きます。数値の正規表現が必要な場合、通常はこの正規表現から始めて、不要な部分を編集します。

NB float は、文字列を解析するだけでなく、かなり複雑な計算である float に変換する必要があるため、正規表現よりも遅くなる可能性があると考えられます。しかし、それがあったとしても、それはまだ驚くべきことです.

于 2010-02-11T23:36:38.143 に答える
0

最初に正規表現をコンパイルしてみるかもしれませんが、それでも遅くなると思います。

また、計算を行うために文字列が数値であるかどうかを知りたい場合は、とにかく強制する必要があります。

于 2010-02-11T22:25:13.193 に答える