parsing 数値 判定 - Pythonで文字列をfloatまたはintに解析するにはどうすればよいですか?





12 Answers

def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)
数値型 変換 範囲

Pythonでは、 "545.2222"ような数値文字列を対応するfloat値、 542.2222にどのように解析できますか? または、文字列"31"を整数"31"解析します。

私は浮動小数点数を浮動小数点数に解析する方法と、(別に) 整数を整数に変換する方法を知りたいだけです。




これはここで言及する価値のある別の方法です、 ast.literal_eval

これは、値を解析する必要なく、信頼できないソースからPython式を含む文字列を安全に評価するために使用できます。

つまり、安全な「評価」は、

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31



ローカリゼーションとコンマ

例外をスローするfloat("545,545.2222")ような場合には、数値の文字列表現でカンマの可能性を考慮する必要があります。 代わりに、 localeメソッドを使用して文字列を数値に変換し、カンマを正しく解釈します。 locale.atofメソッドは、ロケールが目的の番号規則のために設定されると、フロートに一度に変換されます。

例1 - 米国の番号規則

米国と英国では、カンマを千単位の区切り記号として使用できます。 この例では、アメリカのロケールでは、カンマがセパレータとして正しく処理されます。

>>> import locale
>>> a = u'545,545.2222'
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.atof(a)
545545.2222
>>> int(locale.atof(a))
545545
>>>

例2 - ヨーロッパの番号規則

世界大部分の国では 、ピリオドの代わりにカンマが小数点記号として使用されています。 フランス語のロケールを使用したこの例では、コンマは小数点として正しく処理されます。

>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222

メソッドlocale.atoiも使用できますが、引数は整数でなければなりません。




第三者のモジュールを嫌う人なら、 fastnumbersモジュールをチェックすることができます。 これはfast_realという関数を提供しています。この関数は、この質問が尋ねていることを正確に行い、純粋なPythonの実装よりも高速です。

>>> from fastnumbers import fast_real
>>> fast_real("545.2222")
545.2222
>>> type(fast_real("545.2222"))
float
>>> fast_real("31")
31
>>> type(fast_real("31"))
int



Pythonでは、 "545.2222"のような数値文字列を対応するfloat値、542.2222にどのように解析できますか? または、文字列 "31"を整数31に解析します。 私は浮動小数点数を浮動小数点数に解析する方法と、(別に)整数を整数に変換する方法を知りたいだけです。

これらを別々に行うことを頼むことは良いことです。 あなたがそれらを混ぜているなら、後で問題のために自分自身を設定しているかもしれません。 簡単な答えは次のとおりです。

"545.2222"を浮かべる:

>>> float("545.2222")
545.2222

"31"を整数にする:

>>> int("31")
31

他の変換、文字列とリテラルとの間のint:

さまざまな拠点からの変換があります。事前に拠点を知っておく必要があります(デフォルトは10です)。 Pythonがそのリテラルに期待するものに接頭辞を付けたり(下記参照)、接頭辞を削除することができます。

>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31

事前にベースを知っていないにもかかわらず、正しい接頭辞を持つことがわかっている場合、ベースとして0を渡すと、Pythonはこれを推測できます:

>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31

他のベースの非小数(すなわち整数)リテラル

しかし、自分のコードがハードコードされた特定の値を明確に表現することを目的としている場合は、ベースから変換する必要はないかもしれません - Pythonが正しい構文で自動的にそれを行えるようにすることができます。

apropos接頭辞を使用して、以下のリテラルで整数への自動変換を行うことができます。 これらはPython 2と3で有効です:

バイナリ、プレフィックス0b

>>> 0b11111
31

8進数、接頭辞0o

>>> 0o37
31

16進数、接頭辞0x

>>> 0x1f
31

これは、バイナリフラグ、コード内のファイルパーミッション、または色の16進値を記述するときに役立ちます。たとえば、引用符は使用しません。

>>> 0b10101 # binary flags
21
>>> 0o755 # read, write, execute perms for owner, read & ex for group & others
493
>>> 0xffffff # the color, white, max values for red, green, and blue
16777215

あいまいなPython 2の8進数をPython 3と互換性を持たせる

Python 2では、0で始まる整数を見ると、これは(廃止予定の)8進数の構文です。

>>> 037
31

それは価値が37べきであるように見えるので悪いです。 そのため、Python 3では、 SyntaxError

>>> 037
  File "<stdin>", line 1
    037
      ^
SyntaxError: invalid token

Python 2の8進数を0と2の接頭辞の両方で動作する8進数に変換します:

>>> 0o37
31



YAMLパーサーは、あなたの文字列がどんなデータ型であるかを理解するのに役立ちます。 yaml.load()使用すると、 type(result)を使用してtype(result)をテストできます:

>>> import yaml

>>> a = "545.2222"
>>> result = yaml.load(a)
>>> result
545.22220000000004
>>> type(result)
<type 'float'>

>>> b = "31"
>>> result = yaml.load(b)
>>> result
31
>>> type(result)
<type 'int'>

>>> c = "HI"
>>> result = yaml.load(c)
>>> result
'HI'
>>> type(result)
<type 'str'>



私はこの機能を

import ast

def parse_str(s):
   try:
      return ast.literal_eval(str(s))
   except:
      return

文字列をその型に変換します

value = parse_str('1')  # Returns Integer
value = parse_str('1.5')  # Returns Float



def num(s):
"""num(s)
num(3),num(3.7)-->3
num('3')-->3, num('3.7')-->3.7
num('3,700')-->ValueError
num('3a'),num('a3'),-->ValueError
num('3e4') --> 30000.0
"""
try:
    return int(s)
except ValueError:
    try:
        return float(s)
    except ValueError:
        raise ValueError('argument is not a string of number')



これは https://.com/a/33017514/5973334 修正版ですhttps://.com/a/33017514/5973334

これは、文字列を解析して、文字列の内容に応じてintまたはfloatいずれかを返します。 解析例外が発生するか、予期しない動作が発生する可能性があります。

  def get_int_or_float(v):
        number_as_float = float(v)
        number_as_int = int(number_as_float)
        return number_as_int if number_as_float == number_as_int else 
        number_as_float



Pythonで型キャストするには、型のコンストラクタfuntionsを使用し、文字列(またはキャストしようとしている値)をパラメータとして渡します。

例えば:

>>>float("23.333")
   23.333

背後では、pythonは__float__メソッドのオブジェクトを呼び出しています。これはパラメータの浮動小数点表現を返すべきです。 float(myobject)を使用してfloatにキャストできるように、 __float__メソッドで独自の型(クラスを使用)を定義できるので、これは特に強力です。




つかいます:

>>> str_float = "545.2222"
>>> float(str_float)
545.2222
>>> type(_) # Check its type
<type 'float'>

>>> str_int = "31"
>>> int(str_int)
31
>>> type(_) # Check its type
<type 'int'>



あなたの質問の別の解釈があります(ヒント:あいまいです)。 次のようなものを探している可能性があります。

def parseIntOrFloat( aString ):
    return eval( aString )

それはこのように動作します...

>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545

理論的には、注射脆弱性があります。 文字列は、例えば"import os; os.abort()" 。 しかし、文字列がどこから来るのかについての背景なしに、理論的な推測の可能性がある。 問題はあいまいなので、この脆弱性が実際に存在するかどうかはまったく明らかではありません。




Related