web-dev-qa-db-ja.com

Pythonで文字列をfloatまたはintに解析する方法を教えてください。

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

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

1987
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
2345
Harley Holcombe
def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)
474
Javier

文字列が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がfalseを返す可能性がほとんどないことを生み出します。 float(...)行のコードは、文字列の内容とは無関係の1000の理由で失敗することがあります。しかし、ライフクリティカルなソフトウェアをPythonのようなアヒルタイプのプロトタイプ言語で書いているのであれば、もっと大きな問題があります。

464
Eric Leschinski

これはここで言及するに値するもう一つの方法です。 ast.literal_eval

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

つまり、安全な「評価」

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
114
wim
float(x) if '.' in x else int(x)
75
Dino Viehland

地域化とカンマ

例外をスローする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も利用可能ですが、引数は整数であるべきです。

57
Mark Chackerian

Users codelogic および harley は正しいですが、文字列が整数(たとえば545)であることがわかっている場合は、最初にfloatにキャストしなくてもint( "545")を呼び出すことができます。

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

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

それらがすべて同じタイプであれば、それは良いことです。

23
Chris Cameron

もしあなたがサードパーティのモジュールに嫌いでなければ、 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
23
SethMMorton

その質問は少し古いようです。しかし、似たようなもの、つまりintegerまたはfloatを返す関数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'
19
krzym

Pythonでは、 "545.2222"のような数値文字列を対応するfloat値542.2222に解析する方法を教えてください。または、文字列 "31"を整数の31に解析しますか。 フロート文字列をフロートに、そして(別々に)int文字列をintに解析する方法を知りたいだけです。

あなたがこれらを別々にするように頼むのは良いことです。あなたがそれらを混ぜているなら、あなたは後で問題にあなた自身を準備しているかもしれません。簡単な答えは:

フロートする"545.2222"

>>> float("545.2222")
545.2222

"31"を整数に変換:

>>> int("31")
31

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

さまざまな拠点からの変換。事前にその拠点を知っておく必要があります(デフォルトは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進数(つまり整数)リテラル

あなた自身のコードがハードコードされた特定の値を明確に表現することをあなたの動機としているのであれば、しかしながら、あなたはベースから変換する必要はないかもしれません。

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進数を0o接頭辞を付けて2と3の両方で機能する8進数に変換します。

>>> 0o37
31
18
Aaron Hall

float("545.2222")int(float("545.2222"))

15
codelogic

私はそのためにこの機能を使います

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
13
Shameem

_ yaml _ /パーサーを使用すると、文字列がどのデータ型であるかを判断できます。 yaml.load()を使うと、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'>
13
Rafe
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
11
Totoro
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')
7
Jerry T

これを正しく行うには、丸めを考慮に入れる必要があります。

すなわちint(5.1)=> 5 int(5.6)=> 5 - 間違っている、6でなければならないのでint(5.6 + 0.5)=> 6

def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)
6
Nick

時々文字列はnumberにキャストする前に準備され正規化されなければならないので、私は誰も正規表現について言及しなかったのに驚いています

import re
def parseNumber(value, as_int=False):
    try:
        number = float(re.sub('[^.\-\d]', '', value))
        if as_int:
            return int(number + 0.5)
        else:
            return number
    except ValueError:
        return float('nan')  # or None if you wish

使用法:

parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0

ところで、あなたに番号があることを確認するための何かがあります。

import numbers
def is_number(value):
    return isinstance(value, numbers.Number)
    # will work with int, float, long, Decimal
5

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

例えば:

>>>float("23.333")
   23.333

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

4
qwerty12345

Pythonは、このように柔軟に1つのライナーで解析することができます。

str = "545.2222"
print ("int: ", + int(float(a)))
print ("float: ", +(float(a)))
4
Harry_pb

これは修正されたバージョンです / https://stackoverflow.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
3
Kuzeko

str()を使用して任意の変数を文字列に変換し、int()を使用して文字列の整数を整数に変換し、float()を使用して文字列の浮動小数点数を浮動小数点数に変換できます。

str_to_float = float("545.2222")
str_to_int = int("31")
2

つかいます:

def num(s):
    try:
        for each in s:
            yield int(each)
    except ValueError:
        yield float(each)
a = num(["123.55","345","44"])
print a.next()
print a.next()

これは私が思い付くことができた最もPythonicの方法です。

1
SeasonalShot

これは、objectname__(strname__だけでなく)をintname__またはfloatname__に変換する関数です。指定された実際の文字列が似ているかintname__またはfloatname__に基づきます。さらに、__floatメソッドと__int__メソッドの両方を持つオブジェクトの場合、デフォルトでは__float__を使用します

def conv_to_num(x, num_type='asis'):
    '''Converts an object to a number if possible.
    num_type: int, float, 'asis'
    Defaults to floating point in case of ambiguity.
    '''
    import numbers

    is_num, is_str, is_other = [False]*3

    if isinstance(x, numbers.Number):
        is_num = True
    Elif isinstance(x, str):
        is_str = True

    is_other = not any([is_num, is_str])

    if is_num:
        res = x
    Elif is_str:
        is_float, is_int, is_char = [False]*3
        try:
            res = float(x)
            if '.' in x:
                is_float = True
            else:
                is_int = True
        except ValueError:
            res = x
            is_char = True

    else:
        if num_type == 'asis':
            funcs = [int, float]
        else:
            funcs = [num_type]

        for func in funcs:
            try:
                res = func(x)
                break
            except TypeError:
                continue
        else:
            res = x
0
Abhishek Bhatia

つかいます:

>>> 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'>
0
amirteymuri