python - 추출 - 파이썬 자연수




문자열이 숫자(float)인지 어떻게 확인합니까? (20)

어느 쪽이 추악하고 느릴뿐만 아니라

나는 둘 다 논쟁하곤했다.

정규식이나 다른 문자열 파싱은 더럽고 느려질 수 있습니다.

위의 것보다 훨씬 빠른 것이있을 수 있는지 잘 모르겠습니다. 함수를 호출하고 리턴합니다. 스택 프레임을 광범위하게 검색하지 않고 가장 일반적인 예외가 잡히기 때문에 Try / Catch는 많은 오버 헤드를 유발하지 않습니다.

문제는 모든 숫자 변환 함수에는 두 가지 종류의 결과가 있다는 것입니다.

  • 숫자가 유효한 경우 숫자
  • 유효한 숫자를 파싱 할 수 없음을 나타내는 상태 코드 (예 : errno를 통해) 또는 예외.

C는 (예로서) 여러 가지 방법으로 해킹합니다. 파이썬은 그것을 명확하고 명백하게 설명합니다.

이 일을하기위한 코드가 완벽하다고 생각합니다.

파이썬에서 문자열을 숫자로 표현할 수 있는지 확인하는 가장 좋은 방법은 무엇입니까?

현재 현재 가지고있는 기능은 다음과 같습니다.

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

추악하고 느린 것만이 아닌, 어색한 것처럼 보입니다. 그러나 주 함수에서 float 를 호출하는 것이 더 float 더 나은 방법을 찾지 못했습니다.


추악하고 느린 것만이 아닌, 어색한 것처럼 보입니다.

익숙해지는 데는 다소 시간이 걸릴 수 있지만,이를 수행하는 것은 비법입니다. 이미 지적했듯이 대안은 더 나쁘다. 그러나 이런 방식으로 일을하는 또 다른 이점은 다형성입니다.

오리 타이핑의 핵심 아이디어는 "오리처럼 걷고 말하면 오리야." 어떤 것을 float으로 변환 할 수 있는지 결정하는 방법을 변경할 수 있도록 문자열을 서브 클래스 화해야한다고 결정하면 어떻게됩니까? 또는 다른 객체를 완전히 테스트하기로 결정했다면 어떻게 될까요? 위 코드를 변경하지 않고도 이러한 작업을 수행 할 수 있습니다.

다른 언어는 인터페이스를 사용하여 이러한 문제를 해결합니다. 어떤 솔루션이 다른 스레드를 위해 더 나은지에 대한 분석을 저장하겠습니다. 요점은, 파이썬은 공식적으로 오리를 타이핑하는 쪽입니다. 파이썬에서 많은 프로그래밍을 할 계획이라면 아마 이런 식의 구문에 익숙해 져야 할 것입니다. 당신은 물론 그것을 좋아해야한다).

고려해야 할 다른 한 가지 : Python은 많은 다른 언어와 비교하여 예외를 던지고 잡는 데 꽤 빠릅니다 (예 : .Net보다 30 배 빠름). Heck, 언어 자체는 예외적이지 않은 정상적인 프로그램 조건 (for 루프를 사용할 때마다)을 전달하기 위해 예외를 throw합니다. 따라서 중요한 문제를 발견 할 때까지이 코드의 성능 측면에 대해 너무 걱정하지 않아도됩니다.


Alfe가 복잡한 작업을 할 때마다 별도로 float을 확인할 필요가 없다고 지적한 후에 업데이트되었습니다.

def is_number(s):
    try:
        complex(s) # for int, long, float and complex
    except ValueError:
        return False

    return True

이전에 말하기를 : 드물게 플로트로 표현할 수없는 복소수 (예 : 1 + 2i)를 확인해야하는 경우도 있습니다.

def is_number(s):
    try:
        float(s) # for int, long and float
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False

    return True

float ()은 특히이를위한 것이므로, 부동으로 캐스팅하고 ValueError를 잡는 것이 가장 빠른 방법 일 것입니다. 문자열 파싱 (정규식 등)이 필요한 다른 작업은이 작업을 위해 조정되지 않았기 때문에 느려질 수 있습니다. 내 0.02 달러.


귀하의 코드는 나에게 잘 보인다.

아마도 예외를 사용하기 때문에 코드가 "clunky"하다고 생각할 수 있습니까? 파이썬 프로그래머는 낮은 성능 저하 때문에 코드 가독성을 향상시킬 때 예외를 자유롭게 사용하는 경향이 있습니다.


그래서 모두 함께 넣어, Nan, 무한대 및 복소수 (j가 아닌 i, 즉 1 + 2j로 지정되는 것처럼 보일 것입니다)를 확인하면 결과는 다음과 같습니다.

def is_number(s):
    try:
        n=str(float(s))
        if n == "nan" or n=="inf" or n=="-inf" : return False
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False
    return True

나는 이것이 특히 오래되었다는 것을 안다. 그러나 나는 이것을 발견하는 사람들에게 매우 가치가있을 수있는 가장 높은 표를 얻은 대답으로부터 누락 된 정보를 다룰 수 있다고 믿는다.

입력을 받아 들일 필요가있는 경우 다음의 각 메소드에 대해 각각의 메소드를 연결하십시오. (우리가 0-255가 아닌 정수의 보컬 정의를 사용한다고 가정 할 때)

x.isdigit() 는 x가 정수인지 확인하는 데 적합합니다.

x.replace('-','').isdigit() 는 x가 음수인지 검사하는데 잘 작동한다. (첫 번째 위치에서 체크인한다. x.replace('-','').isdigit() )

x.replace('.','').isdigit() 는 x가 10 진수인지 확인하는데 적합합니다.

x.replace(':','').isdigit() 는 x가 비율인지 확인하는 데 적합합니다.

x.replace('/','',1).isdigit() 는 x가 분수인지 확인하는 데 적합합니다.


문자열에 숫자가 있다고 가정 해 보겠습니다. str = "100949"이고 숫자 만 들어 있는지 확인하고 싶습니다.

if str.isdigit():
returns TRUE or FALSE 

isdigit 워드 프로세서

그렇지 않으면 당신의 방법은 문자열에서 숫자의 발생을 찾기 위해 훌륭하게 작동합니다.



숫자가 아닌 문자열의 경우 try: except: 는 실제로 정규 표현식보다 느립니다. 유효한 숫자의 문자열의 경우 정규 표현식이 더 느립니다. 따라서 적절한 방법은 입력 내용에 따라 다릅니다.

성능 바인드를 발견하면 fastnumbers 라는 fastnumbers 를 제공하는 fastnumbers 라는 새로운 타사 모듈을 사용할 수 있습니다. 전체 공개, 나는 저자 야. 그 결과를 아래의시기에 포함 시켰습니다.

from __future__ import print_function
import timeit

prep_base = '''\
x = 'invalid'
y = '5402'
z = '4.754e3'
'''

prep_try_method = '''\
def is_number_try(val):
    try:
        float(val)
        return True
    except ValueError:
        return False

'''

prep_re_method = '''\
import re
float_match = re.compile(r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$').match
def is_number_re(val):
    return bool(float_match(val))

'''

fn_method = '''\
from fastnumbers import isfloat

'''

print('Try with non-number strings', timeit.timeit('is_number_try(x)',
    prep_base + prep_try_method), 'seconds')
print('Try with integer strings', timeit.timeit('is_number_try(y)',
    prep_base + prep_try_method), 'seconds')
print('Try with float strings', timeit.timeit('is_number_try(z)',
    prep_base + prep_try_method), 'seconds')
print()
print('Regex with non-number strings', timeit.timeit('is_number_re(x)',
    prep_base + prep_re_method), 'seconds')
print('Regex with integer strings', timeit.timeit('is_number_re(y)',
    prep_base + prep_re_method), 'seconds')
print('Regex with float strings', timeit.timeit('is_number_re(z)',
    prep_base + prep_re_method), 'seconds')
print()
print('fastnumbers with non-number strings', timeit.timeit('isfloat(x)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with integer strings', timeit.timeit('isfloat(y)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with float strings', timeit.timeit('isfloat(z)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print()
Try with non-number strings 2.39108395576 seconds
Try with integer strings 0.375686168671 seconds
Try with float strings 0.369210958481 seconds

Regex with non-number strings 0.748660802841 seconds
Regex with integer strings 1.02021503448 seconds
Regex with float strings 1.08564686775 seconds

fastnumbers with non-number strings 0.174362897873 seconds
fastnumbers with integer strings 0.179651021957 seconds
fastnumbers with float strings 0.20222902298 seconds

보시다시피

  • try: except: 숫자 입력은 빠르지 만 잘못된 입력은 매우 느립니다.
  • 정규식은 입력이 유효하지 않은 경우 매우 효율적입니다.
  • fastnumbers 는 두 경우 모두에서 이긴다.

이 대답은 문자열을 찾는 예제가있는 함수를 갖는 단계별 가이드를 제공합니다.

  • 양의 정수
  • 양수 / 음수 - 정수 / 부동 소수점
  • 번호를 확인하면서 "NaN"(숫자가 아님) 문자열을 버리는 방법은 무엇입니까?

문자열이 양의 정수인지 확인하십시오.

isdigit() 를 사용하여 주어진 문자열이 양의 정수인지 확인할 수 있습니다.

샘플 결과 :

# For digit
>>> '1'.isdigit()
True
>>> '1'.isalpha()
False

양수 / 음수로 문자열 확인 - 정수 / 부동

str.isdigit() 는 문자열이 음수 또는 부동 소수이면 False 반환합니다. 예 :

# returns `False` for float
>>> '123.3'.isdigit()
False
# returns `False` for negative number
>>> '-123'.isdigit()
False

음의 정수를 확인하고 float 을 확인하려면 사용자 정의 함수를 작성하여 다음 같이 점검하십시오.

def is_number(n):
    try:
        float(n)   # Type-casting the string to `float`.
                   # If string is not a valid `float`, 
                   # it'll raise `ValueError` exception
    except ValueError:
        return False
    return True

샘플 실행 :

>>> is_number('123')    # positive integer number
True

>>> is_number('123.4')  # positive float number
True

>>> is_number('-123')   # negative integer number
True

>>> is_number('-123.4') # negative `float` number
True

>>> is_number('abc')    # `False` for "some random" string
False

번호를 확인하는 동안 "NaN"(숫자가 아님) 문자열을 버립니다.

위의 함수는 "NAN"(숫자가 아님) 문자열에 대해 True 를 반환합니다. 왜냐하면 Python에서는 숫자가 아닌 유효한 float를 나타 내기 때문입니다. 예 :

>>> is_number('NaN')
True

숫자가 "NaN"인지 확인하려면 math.isnan() 을 다음과 같이 사용할 수 있습니다.

>>> import math
>>> nan_num = float('nan')

>>> math.isnan(nan_num)
True

또는 이것을 확인하기 위해 추가 라이브러리를 가져 오지 않으려면 == 사용하여 자체 라이브러리와 비교하여 간단히 확인할 수 있습니다. nan float을 자체와 비교하면 Python은 False 반환합니다. 예 :

# `nan_num` variable is taken from above example
>>> nan_num == nan_num
False

따라서 위의 함수 is_number"NaN" 대해 False 를 반환하도록 업데이트 할 수 있습니다 .

def is_number(n):
    is_number = True
    try:
        num = float(n)
        # check for "nan" floats
        is_number = num == num   # or use `math.isnan(num)`
    except ValueError:
        is_number = False
    return is_number

샘플 실행 :

>>> is_number('Nan')   # not a number "Nan" string
False

>>> is_number('nan')   # not a number string "nan" with all lower cased
False

>>> is_number('123')   # positive integer
True

>>> is_number('-123')  # negative integer
True

>>> is_number('-1.12') # negative `float`
True

>>> is_number('abc')   # "some random" string
False

추신 : 숫자의 유형에 따라 각 수표에 대한 각 작업은 추가 오버 헤드가 있습니다. 요구 사항에 맞는 is_number 함수의 버전을 선택하십시오.


이 시도.

 def is_number(var):
    try:
       if var == int(var):
            return True
    except Exception:
        return False

한가지 예외는 다음과 같습니다. 'NaN'문자열

is_number가 'NaN'에 대해 FALSE를 반환하도록하려면 파이썬이 번호가 아닌 숫자로 변환하여이 코드가 작동하지 않습니다 (ID 문제에 대한 이야기).

>>> float('NaN')
nan

그렇지 않으면, 나는 지금 광범위하게 사용하는 코드 조각에 대해 실제로 감사해야합니다. :)

지.


int 사용하려면 다음을 수행하십시오.

>>> "1221323".isdigit()
True

그러나 float 을 위해서는 몇 가지 트릭이 필요합니다 .-). 모든 부유물 번호는 1 점이 있습니다 ...

>>> "12.34".isdigit()
False
>>> "12.34".replace('.','',1).isdigit()
True
>>> "12.3.4".replace('.','',1).isdigit()
False

또한 음수의 경우 lstrip() 추가하십시오.

>>> '-12'.lstrip('-')
'12'

그리고 이제 우리는 보편적 인 방법을 얻습니다 :

>>> '-12.34'.lstrip('-').replace('.','',1).isdigit()
True
>>> '.-234'.lstrip('-').replace('.','',1).isdigit()
False

RyanN는 제안한다.

NaN 및 Inf에 대해 False를 반환하려면 행을 x = float (s)로 변경합니다. return (x == x) 및 (x - 1! = x). 이것은 Inf와 NaN을 제외한 모든 float에 대해 True를 반환해야합니다.

그러나 이것은 충분히 작동하지 않습니다. 왜냐하면 충분히 큰 수레 x-1 == x가 true를 반환 하기 때문입니다 . 예를 들어,2.0**54 - 1 == 2.0**54


다음과 같이 사용하면 모든 경우를 처리합니다.

import re
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3') 
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '.3')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3sd')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3')

전체 문자열을 숫자로 표현할 수 있는지 알고 싶다면 regexp를 사용하거나 (또는 ​​float을 문자열로 변환하고 원본 문자열과 비교하는 것이 좋을 것입니다. 그러나 그 속도는 매우 빠르지 않습니다) ).


True 및 False보다 유용한 값을 리턴하여 유용한 방법으로 예외 기술을 일반화 할 수 있습니다. 예를 들어이 함수는 문자열을 따옴표로 묶지 만 숫자 만 남겨 둡니다. R에 대한 몇 가지 변수 정의를 만들기 위해 빠르고 필터가 필요한 것입니다.

import sys

def fix_quotes(s):
    try:
        float(s)
        return s
    except ValueError:
        return '"{0}"'.format(s)

for line in sys.stdin:
    input = line.split()
    print input[0], '<- c(', ','.join(fix_quotes(c) for c in input[1:]), ')'

또한 언급 한 기능을 사용했지만 곧 "Nan", "Inf"및 변형 된 문자열을 숫자로 간주합니다. 그래서 나는 당신에게 함수의 개선 된 버전을 제안합니다, 그 타입의 입력에서 false를 반환 할 것이고 "1e3"변형을 실패하지 않을 것입니다 :

def is_float(text):
    try:
        float(text)
        # check for nan/infinity etc.
        if text.isalpha():
            return False
        return True
    except ValueError:
        return False

여기에 내 간단한 방법이 있습니다. 어떤 문자열을 반복하고 있다고 가정 해 봅시다. 숫자로 판명되면 배열에 추가하고 싶습니다.

try:
    myvar.append( float(string_to_check) )
except:
    continue

myvar.apppend를 숫자로 밝혀지면 문자열로 처리하려는 작업으로 바꿉니다. 아이디어는 float () 연산을 사용하고 반환 된 에러를 사용하여 문자열이 숫자인지 여부를 결정하는 것입니다.





type-conversion