문제

파이썬에서 어떻게 "545.2222" 해당 플로트 값으로 545.2222? 또는 문자열을 구문 분석하십시오 "31" 정수에, 31?

나는 단지 구문 분석 방법을 알고 싶다 뜨다 str a float, 및 (개별적으로) an int str an int.

도움이 되었습니까?

해결책

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

다른 팁

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

문자열이 플로트인지 확인하는 Python Method :

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

이 기능의 더 길고 정확한 이름은 다음과 같습니다. is_convertible_to_float(value)

무엇이며, 플로트가 아닙니다 파이썬 당신을 놀라게 할 수 있습니다 :

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(...) 문자열의 내용과 관련이없는 수천 가지 이유로 코드 라인이 실패 할 수 있습니다. 그러나 Python과 같은 오리 타자 프로토 타입 언어로 생명 크리티컬 소프트웨어를 작성하는 경우 훨씬 더 큰 문제가 있습니다.

이것은 여기서 언급 할 가치가있는 또 다른 방법입니다. ast.literal_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- 미국 번호 규칙

미국과 영국에서는 쉼표가 수천 개의 분리기로 사용할 수 있습니다. 미국 로케일 의이 예에서 쉼표는 분리기로 올바르게 처리됩니다.

>>> 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 그것은이 질문이 요구하는 것을 정확하게 수행하고 순수한 파이썬 구현보다 빠르게 수행합니다.

>>> 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)라는 것을 알고 있다면 먼저 float를 주조하지 않고 int ( "545") 호출 할 수 있습니다.

문자열이 목록에 있으면 맵 기능도 사용할 수 있습니다.

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

그들이 모두 같은 유형 인 경우에만 좋습니다.

질문은 조금 오래된 것 같습니다. 그러나 비슷한 것을 만드는 함수 인 parsestr를 제안하겠습니다. 물론 코드는 원하는대로 만 수행하도록 조정 될 수 있습니다.

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

파이썬에서 "545.2222"와 같은 숫자 문자열을 해당 플로트 값 542.2222에 어떻게 구문 분석 할 수 있습니까? 또는 문자열 "31"을 정수, 31에 구문 분석합니까?플로트 문자열을 플로트에 구문 분석하고 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

다른베이스의 비 정도 (예 : 정수) 리터럴

동기 부여가 자신의 코드가 하드 코딩 된 특정 값을 명확하게 나타내는 것이라면,베이스에서 변환 할 필요가 없을 수도 있습니다. Python이 올바른 구문으로 자동으로 수행하도록 할 수 있습니다.

Apropos Prefixes를 사용하여 정수로 자동 변환 할 수 있습니다. 다음 리터럴. 이들은 Python 2 및 3에 유효합니다.

이진, 접두사 0b

>>> 0b11111
31

10 대, 접두사 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 Octals를 Python 3과 호환합니다

Python 2에서 0으로 시작하는 정수가 보이면 (감가 상각 된) Octal 구문입니다.

>>> 037
31

가치가 있어야하는 것처럼 보이기 때문에 나쁘다 37. Python 3에서는 이제 a SyntaxError:

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

Python 2 Octals를 2와 3에서 작동하는 옥탈로 변환합니다. 0o 접두사:

>>> 0o37
31

float("545.2222") 그리고 int(float("545.2222"))

그만큼 Parser는 문자열이 무엇인지 파악할 수 있도록 도와 줄 수 있습니다. 사용 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')

이 작업을 제대로 수행하려면 반올림을 고려해야합니다.

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

숫자로 캐스팅하기 전에 때때로 문자열이 준비되고 정규화되어야하기 때문에 Regex를 언급 한 사람은 아무도 없다는 것에 놀랐습니다.

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

파이썬에서 타입 캐스트하려면 유형의 생성자 기능을 사용하여 문자열 (또는 캐스트하려는 값)을 매개 변수로 전달하십시오.

예를 들어:

>>>float("23.333")
   23.333

무대 뒤에서 파이썬은 물체를 호출하고 있습니다 __float__ 매개 변수의 플로트 표현을 반환 해야하는 방법. 이것은 자신의 유형 (클래스 사용)을 __float__ 플로트 (myObject)를 사용하여 플로트에 캐스팅 할 수 있도록 방법.

이것은 수정 된 버전입니다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

사용:

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

이것은 내가 생각해 낼 수있는 가장 피스닉적인 방법입니다.

사용:

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