文字列をfloatまたはintに解析するにはどうすればよいですか?

2008年12月19日に質問されました。  ·  閲覧回数 4.1M回  ·  ソース

Tristan Havelick picture
2008年12月19日

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

float strfloatに解析する方法と、(個別に) int strintに解析する方法を知りたいだけです。

回答

Harley Holcombe picture
2008年12月19日
2735
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
Javier picture
2008年12月19日
533
def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)
Eric Leschinski picture
2014年01月05日
522

文字列がfloatであるかどうかを確認するPythonメソッド:

def is_float(value):
  try:
    float(value)
    return True
  except:
    return False

この関数のより長く正確な名前は次のようになります: is_convertible_to_float(value)

Pythonのフロートとは何か、そしてそうではないことはあなたを驚かせるかもしれません:

val                   is_float(val) Note
--------------------  ----------   --------------------------------
""                    False        Blank string
"127"                 True         Passed string
True                  True         Pure sweet Truth
"True"                False        Vile contemptible lie
False                 True         So false it becomes true
"123.456"             True         Decimal
"      -127    "      True         Spaces trimmed
"\t\n12\r\n"          True         whitespace ignored
"NaN"                 True         Not a number
"NaNanananaBATMAN"    False        I am Batman
"-iNF"                True         Negative infinity
"123.E4"              True         Exponential notation
".1"                  True         mantissa only
"1,234"               False        Commas gtfo
u'\x30'               True         Unicode is fine.
"NULL"                False        Null is not special
0x3fade               True         Hexadecimal
"6e7777777777777"     True         Shrunk to infinity
"1.797693e+308"       True         This is max value
"infinity"            True         Same as inf
"infinityandBEYOND"   False        Extra characters wreck it
"12.34.56"            False        Only one dot allowed
u'四'                 False        Japanese '4' is not a float.
"#56"                 False        Pound sign
"56%"                 False        Percent of what?
"0E0"                 True         Exponential, move dot 0 places
0**0                  True         0___0  Exponentiation
"-5e-5"               True         Raise to a negative number
"+1e1"                True         Plus is OK with exponent
"+1e1^5"              False        Fancy exponent not interpreted
"+1e1.3"              False        No decimals in exponent
"-+1"                 False        Make up your mind
"(1)"                 False        Parenthesis is bad

あなたはあなたが数字が何であるか知っていると思いますか? あなたは思ったほど良くありません! 大きな驚きではありません。

ライフクリティカルなソフトウェアでこのコードを使用しないでください。

この方法で幅広い例外をキャッチし、カナリアを強制終了し、例外をゴブリングすると、有効なfloat asstringがfalseを返す可能性がわずかに発生します。 コードのfloat(...)行は、文字列の内容とは関係のない1000の理由のいずれかで失敗する可能性があります。 しかし、Pythonのようなダックタイピングのプロトタイプ言語でライフクリティカルなソフトウェアを作成している場合は、はるかに大きな問題が発生します。

wim picture
2012年03月01日
142

これは、ここで言及するに値する別のメソッド、 ast.literal_evalです。

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

つまり、安全な「評価」

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
Dino Viehland picture
2008年12月19日
79
float(x) if '.' in x else int(x)
Mark Chackerian picture
2013年07月24日
74

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

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

例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も使用できますが、引数は整数である必要があります。

SethMMorton picture
2014年08月14日
28

サードパーティのモジュールを嫌がらない場合は、 fast_realと呼ばれる関数を提供します。

>>> 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
user44484 picture
2008年12月19日
26

ユーザーはcodelogicハーレーが正しいですが、あなたは、文字列が整数であることがわかっている場合に注意してください(例えば、545)あなたはフロートへの最初の鋳造なしのint(「545」)を呼び出すことができます。

文字列がリストにある場合は、map関数も使用できます。

>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>

それらがすべて同じタイプである場合にのみ良いです。

Aaron Hall picture
2015年07月23日
23

Pythonで、「545.2222」のような数値文字列を対応するfloat値542.2222に解析するにはどうすればよいですか?

これらを別々に行うように依頼するのは良いことです。 それらを混合している場合は、後で問題が発生する可能性があります。 簡単な答えは次のとおりです。

フロートする"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

他の基数からの非10進数(つまり整数)リテラル

ただし、独自のコードでハードコードされた特定の値を明確に表すことが目的の場合は、ベースから変換する必要がない場合があります。正しい構文を使用して、Pythonに自動的に変換させることができます。

aproposプレフィックスを使用して、次のリテラルを使用して整数に自動変換することができます。 これらはPython2および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

あいまいなPython2オクタルをPython3と互換性のあるものにする

Python 2で、0で始まる整数が表示された場合、これは(非推奨の)8進構文です。

>>> 037
31

値は37必要があるように見えるので、これは悪いことです。 したがって、Python 3では、 SyntaxErrorます。

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

Python 2の8進数を、接頭辞0o付けて2と3の両方で機能する8進数に変換します。

>>> 0o37
31
krzym picture
2011年09月29日
21

質問は少し古いようです。 しかし、似たような関数parseStrを提案しましょう。つまり、整数または浮動小数点数を返し、特定のASCII文字列をそれらのいずれにも変換できない場合は、そのまま返します。 もちろん、コードは必要なことだけを実行するように調整される場合があります。

   >>> import string
   >>> parseStr = lambda x: x.isalpha() and x or x.isdigit() and \
   ...                      int(x) or x.isalnum() and x or \
   ...                      len(set(string.punctuation).intersection(x)) == 1 and \
   ...                      x.count('.') == 1 and float(x) or x
   >>> parseStr('123')
   123
   >>> parseStr('123.3')
   123.3
   >>> parseStr('3HC1')
   '3HC1'
   >>> parseStr('12.e5')
   1200000.0
   >>> parseStr('12$5')
   '12$5'
   >>> parseStr('12.2.2')
   '12.2.2'