質問

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

解析方法を知りたいだけです 浮く strfloat, 、および(別途) 整数 strint.

役に立ちましたか?

解決

>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545

他のヒント

def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)

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

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

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

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

、このように広範な例外をキャッチカナリアを殺し、例外をgobblingは文字列として有効なフロートがfalseを返すこと小さなチャンスを作成します。コードのfloat(...)ラインは、文字列の内容とは関係のない千点のいずれかの理由で失敗することができます。あなたがPythonのようなアヒルタイピングプロトタイプ言語での生活に不可欠なソフトウェアを書いている場合しかし、あなたははるかに大きな問題を持っています。

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

  

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

つまり、安全 'にeval'

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
float(x) if '.' in x else int(x)

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

次のような場合、数値の文字列表現にカンマが含まれる可能性を考慮する必要があります。 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 も使用できますが、引数は整数である必要があります。

あなたは、サードパーティ製のモジュールを嫌うない場合は、

は、 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

ユーザーがのcodelogic ハーレーのが正しいですが、あなたは、文字列は、(例えば、545)の整数であり、知っていれば覚えておいて、あなたは( "545" のintを呼び出すことができます)最初のfloat型にキャストなしています。

あなたの文字列がリストにある場合は、

、あなたにも、マップ機能を使用することができます。

>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
それらはすべて同じタイプなら

それだけでいいです。

質問は少し古いようです。しかし、私は機能を示唆してみましょう、似た何かを作る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'

Python では、「545.2222」のような数値文字列を対応する浮動小数点値 542.2222 に解析するにはどうすればよいですか?それとも文字列「31」を整数 31 に解析しますか?float 文字列を float に解析し、(個別に) int 文字列を int に解析する方法を知りたいだけです。

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

"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

事前にベースが分からなくても、正しいプレフィックスが付けられることが分かっている場合は、次の値を渡すと Python がこれを推測できます。 0 ベースとして:

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

10 進数以外 (すなわち、整数) 他の基底からのリテラル

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

適切な接頭辞を使用すると、整数への自動変換を行うことができます。 次のリテラル. 。これらは 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 進数を、2 と 3 の両方で動作する 8 進数に変換します。 0o 接頭辞:

>>> 0o37
31

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

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

私はそのために、この機能を使用する

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 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
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')

あなたはこれを適切に行うために丸め考慮に入れる必要があります。

すなわち。 INT(5.1)=> 5      INT(5.6)=> 5 - 間違ったので、我々がintを行う6でなければなりません(5.6 + 0.5)=> 6

def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)
時々、文字列が数値にキャストする前に準備して、正規化されなければならないので、

私は驚い誰も正規表現を言及していないよ。

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

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

>>>float("23.333")
   23.333

舞台裏では、Pythonは、パラメータの浮動小数点表現を返す必要があります__float__方法、オブジェクトを呼び出しています。それはフロート(MyObjectに)を使用して、フロートにキャストすることができるようにあなたが__float__メソッドを使用して独自の型(クラスを使用)を定義することができ、これは、特に強力です。

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

これは文字列を解析し、文字列が何を表すかに応じて、intまたはfloatのいずれかを返すようにしようとします。 これは、いくつかの予期しない動作を持ってhref="https://stackoverflow.com/a/1778381/5973334">解析例外や

  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

使用します。

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()

これは私が思い付くことができる最もPython的な方法です。

使用します。

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

これは実際の文字列が提供されている場合に基づき、objectまたはstrするために、任意のint(だけでなく、float)を変換する関数です。のはintまたはfloatのように見えます。さらに、それは__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

ここであなたの質問の別の解釈です(ヒント:それは曖昧です)。それはあなたがこのような何かを探していることが可能です。

def parseIntOrFloat( aString ):
    return eval( aString )

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

>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545
<時間>

理論的には、インジェクションの脆弱性があります。文字列は、例えば"import os; os.abort()"である可能性があります。文字列がどこから来るか上の任意の背景がなければ、しかし、可能性は理論的な憶測です。質問が漠然としているので、この脆弱性が実際に存在するかどう全く明確ではありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top