문제

무엇을 가능한 최상의 방법을 확인하는 문자열로 표시될 수 있습니다 숫자에 Python?

이 기능은 현재 지금:

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

는,하지만 추하고,느린 보랍니다.그러나지 않았을 발견하는 더 나은 방법을하기 때문에 부름 float 에 주요 기능은 더 나쁜 것입니다.

도움이 되었습니까?

해결책

그것은 추악하고 느린 것뿐만 아니라

나는 둘 다 이의를 제기했다.

정규식 또는 기타 문자열 구문 분석 방법은 추악하고 느립니다.

위의 것보다 훨씬 빠를 수 있는지 확신 할 수 없습니다. 함수를 호출하고 반환합니다. 스택 프레임을 광범위하게 검색하지 않고 가장 일반적인 예외가 잡히기 때문에 시도/캐치는 오버 헤드를 많이 소개하지 않습니다.

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

  • 숫자가 유효 한 경우 숫자
  • 상태 코드 (예 : Errno를 통해) 또는 예외는 유효한 숫자를 구문 분석 할 수 없음을 보여줍니다.

C (예 :)이 여러 가지 방법을 해킹합니다. 파이썬은 그것을 명확하고 명확하게 배치합니다.

이 작업을 수행하는 코드가 완벽하다고 생각합니다.

다른 팁

플로트 대신 구문 분석 (긍정적이고 서명되지 않은) 정수를 찾고있는 경우 isdigit() 문자열 객체의 기능.

>>> a = "03523"
>>> a.isdigit()
True
>>> b = "963spam"
>>> b.isdigit()
False

문자열 메소드 - isdigit(): python2, python3

유니 코드 문자열에도 뭔가가 있습니다. 나는 너무 익숙하지 않습니다.유니 코드 - 소수/소수점입니다

tl; dr 최상의 솔루션은입니다 s.replace('.','',1).isdigit()

나는 약간했다 벤치 마크 다른 접근법을 비교합니다

def is_number_tryexcept(s):
    """ Returns True is string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False

import re    
def is_number_regex(s):
    """ Returns True is string is a number. """
    if re.match("^\d+?\.\d+?$", s) is None:
        return s.isdigit()
    return True


def is_number_repl_isdigit(s):
    """ Returns True is string is a number. """
    return s.replace('.','',1).isdigit()

문자열이 숫자가 아닌 경우 제외 블록은 매우 느립니다. 그러나 더 중요한 것은, 시도-제외 방법은 과학 표기법을 올바르게 처리하는 유일한 접근법입니다.

funcs = [
          is_number_tryexcept, 
          is_number_regex,
          is_number_repl_isdigit
          ]

a_float = '.1234'

print('Float notation ".1234" is not supported by:')
for f in funcs:
    if not f(a_float):
        print('\t -', f.__name__)

플로트 표기법 ".1234"는 다음과 같이 뒷받침되지 않습니다.
-Is_number_Regex

scientific1 = '1.000000e+50'
scientific2 = '1e50'


print('Scientific notation "1.000000e+50" is not supported by:')
for f in funcs:
    if not f(scientific1):
        print('\t -', f.__name__)




print('Scientific notation "1e50" is not supported by:')
for f in funcs:
    if not f(scientific2):
        print('\t -', f.__name__)

과학 표기법 "1.000000e+50"은 다음과 같이 뒷받침되지 않습니다.
-Is_number_Regex
-IS_NUMBER_REPL_ISDIGIT
과학 표기법 "1E50"은 다음과 같이 뒷받침되지 않습니다.
-Is_number_Regex
-IS_NUMBER_REPL_ISDIGIT

편집 : 벤치 마크 결과

import timeit

test_cases = ['1.12345', '1.12.345', 'abc12345', '12345']
times_n = {f.__name__:[] for f in funcs}

for t in test_cases:
    for f in funcs:
        f = f.__name__
        times_n[f].append(min(timeit.Timer('%s(t)' %f, 
                      'from __main__ import %s, t' %f)
                              .repeat(repeat=3, number=1000000)))

다음 기능을 테스트 한 경우

from re import match as re_match
from re import compile as re_compile

def is_number_tryexcept(s):
    """ Returns True is string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False

def is_number_regex(s):
    """ Returns True is string is a number. """
    if re_match("^\d+?\.\d+?$", s) is None:
        return s.isdigit()
    return True


comp = re_compile("^\d+?\.\d+?$")    

def compiled_regex(s):
    """ Returns True is string is a number. """
    if comp.match(s) is None:
        return s.isdigit()
    return True


def is_number_repl_isdigit(s):
    """ Returns True is string is a number. """
    return s.replace('.','',1).isdigit()

enter image description here

당신이 고려하고 싶은 예외가 있습니다 : 문자열 'nan'

IS_NUMBER가 'NAN'에 대해 False를 반환하기를 원한다면이 코드는 Python이 숫자가 아닌 숫자의 표현으로 변환함에 따라 작동하지 않습니다 (신원 문제에 대해 이야기).

>>> float('NaN')
nan

그렇지 않으면 실제로 내가 광범위하게 사용하는 코드에 감사드립니다. :)

G.

이건 어때:

'3.14'.replace('.','',1).isdigit()

하나 또는 아니오가있는 경우에만 True가 반환됩니다. 숫자의 문자열로.

'3.14.5'.replace('.','',1).isdigit()

거짓을 반환합니다

편집 : 방금 다른 의견을 보았습니다 ... 추가 .replace(badstuff,'',maxnum_badstuff) 다른 경우에는 수행 할 수 있습니다. 소금을 통과하는 경우 임의의 조미료가 아닌 경우 (참조 :XKCD#974) 이것은 잘 될 것입니다 : p

Alfe가 지적한 후 업데이트 된 후에는 복잡한 처리로 플로트를 별도로 확인할 필요가 없습니다.

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

추악하고 느린 것뿐만 아니라 어리석은 것처럼 보입니다.

익숙해지는 데 약간의 시간이 걸릴 수 있지만 이것은 피스닉 방식입니다. 이미 지적했듯이 대안은 더 나쁩니다. 그러나 이런 식으로 일을하는 또 다른 장점이 있습니다 : 다형성.

오리 타이핑의 중심 아이디어는 "오리처럼 걷고 말하면 오리라는 것"이라는 것입니다. 플로트로 변환 할 수 있는지 확인하는 방법을 변경할 수 있도록 서브 클래스 문자열이 필요하다고 결정하면 어떻게됩니까? 아니면 다른 물체를 완전히 테스트하기로 결정하면 어떻게됩니까? 위의 코드를 변경하지 않고도 이러한 작업을 수행 할 수 있습니다.

다른 언어는 인터페이스를 사용하여 이러한 문제를 해결합니다. 다른 스레드에 대해 어떤 솔루션이 더 나은지 분석을 저장하겠습니다. 그러나 요점은 Python이 방정식의 오리 입력 측면에 결정적으로 결정되며 Python에서 많은 프로그래밍을 할 계획이라면 이와 같은 구문에 익숙해 져야 할 것입니다 (그러나 이것이 의미하지는 않습니다. 당신은 물론 그것을 좋아해야합니다).

당신이 고려하고 싶은 또 다른 것 : Python은 다른 많은 언어들과 비교하여 예외를 던지고 포착하는 데 매우 빠릅니다 (예 : .NET보다 30 배 빠릅니다). 도대체 언어 자체는 심지어 예외를 제외하고 비 법적, 정상적인 프로그램 조건 (루프 용 A를 사용할 때마다)을 전달하기 위해 예외를 던집니다. 따라서 중요한 문제가 발생할 때 까지이 코드의 성능 측면에 대해 너무 걱정하지 않을 것입니다.

을 위한 int 이것을 사용하십시오 :

>>> "1221323".isdigit()
True

이 아니라면 float 우리는 몇 가지 트릭이 필요합니다 ;-). 모든 플로트 번호에는 한 점이 있습니다 ...

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

그냥 C#을 모방합니다.

C#에는 스칼라 값의 구문 분석을 처리하는 두 가지 기능이 있습니다.

  • float.parse ()
  • float.tryparse ()

float.parse () :

def parse(string):
    try:
        return float(string)
    except Exception:
        throw TypeError

참고 : 내가 왜 예외를 TypeError로 변경했는지 궁금하다면 문서는 다음과 같습니다.

float.try_parse () :

def try_parse(string, fail=None):
    try:
        return float(string)
    except Exception:
        return fail;

참고 : 부울 '거짓'을 반환하고 싶지는 않습니다. 여전히 값 유형이기 때문입니다. 실패를 나타 내기 때문에 더 나은 것은 없습니다. 물론, 다른 것을 원한다면 실패 매개 변수를 원하는대로 변경할 수 있습니다.

'parse ()'및 'try_parse ()'를 포함하도록 float를 확장하려면이 메소드를 추가하려면 'float'클래스를 monkeypatch해야합니다.

기존 기능을 존중하려면 코드는 다음과 같아야합니다.

def monkey_patch():
    if(!hasattr(float, 'parse')):
        float.parse = parse
    if(!hasattr(float, 'try_parse')):
        float.try_parse = try_parse

Sidenote : 저는 개인적으로 원숭이 펀칭이라고 부르는 것을 선호합니다.

용법:

float.parse('giggity') // throws TypeException
float.parse('54.3') // returns the scalar value 54.3
float.tryParse('twank') // returns None
float.tryParse('32.2') // returns the scalar value 32.2

그리고 위대한 세이지 파이토나스는 거룩한 See Sharpisus에게 말했다.

숫자가 아닌 끈의 경우 try: except: 실제로 정규 표현보다 느리게됩니다. 유효한 숫자의 문자열의 경우 Regex가 느려집니다. 따라서 적절한 방법은 입력에 따라 다릅니다.

Performance BIND에 있다는 것을 알게되면 새로운 타사 모듈을 사용할 수 있습니다. FastNumbers 그것은 호출 된 함수를 제공합니다 isfloat. 전체 공개, 나는 저자입니다. 아래 타이밍에 결과를 포함 시켰습니다.


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: 숫자 입력은 빠르지 만 잘못된 입력에 대해서는 매우 느 렸습니다.
  • 입력이 유효하지 않으면 Regex가 매우 효율적입니다
  • fastnumbers 두 경우 모두 승리합니다

나는 이것이 특히 오래되었다는 것을 알고 있지만 나는 대답을 추가 할 것입니다. 나는 이것을 찾은 사람에게 매우 가치가있는 가장 높은 투표 답변에서 누락 된 정보를 다루고 있다고 생각합니다.

다음 각 방법에 대해 입력이 필요한 경우 카운트와 연결하십시오. (우리가 0-255가 아닌 정수의 보컬 정의를 사용하고 있다고 가정합니다.)

x.isdigit()X가 정수인지 확인하는 데 효과적입니다.

x.replace('-','').isdigit()X가 음수인지 확인하는 데 적합합니다. (수표 - 첫 번째 위치)

x.replace('.','').isdigit()X가 소수점인지 확인하는 데 효과적입니다.

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

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

float ()가 구체적으로 그 의미이기 때문에 플로트로 캐스팅하고 ValueError를 잡는 것이 아마도 가장 빠른 방법 일 것입니다. 이 작업을 위해 조정되지 않았기 때문에 문자열 구문 분석 (Regex 등)이 필요한 다른 모든 것은 느리게 될 것입니다. 내 $ 0.02.

유니 코드 문자열을 사용할 수 있으며 원하는 것을 수행하는 방법이 있습니다.

>>> s = u"345"
>>> s.isnumeric()
True

또는:

>>> s = "345"
>>> u = unicode(s)
>>> u.isnumeric()
True

http://www.tutorialspoint.com/python/string_isnumeric.htm

http://docs.python.org/2/howto/unicode.html

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

  • 양의 정수
  • 양수/음성 - 정수/플로트
  • 숫자를 확인하는 동안 "Nan"(숫자가 아님) 문자열을 버리는 방법은 무엇입니까?

문자열인지 확인하십시오 긍정적인 정수

당신은 사용할 수 있습니다 str.isdigit() 주어진 문자열이 있는지 확인합니다 긍정적인 정수.

샘플 결과 :

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

문자열을 양수/음수로 확인하십시오 - 정수/플로트

str.isdigit() 보고 False 문자열이 a 부정적인 번호 또는 플로트 번호. 예를 들어:

# 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"(숫자가 아님) 문자열 폐기

위의 기능은 반환됩니다 True "NAN"(숫자가 아님)의 경우, 파이썬의 경우 숫자가 아닙니다. 예를 들어:

>>> is_number('NaN')
True

숫자가 "Nan"인지 확인하려면 math.isnan() 처럼:

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

>>> math.isnan(nan_num)
True

또는이를 확인하기 위해 추가 라이브러리를 가져 오지 않으려면 사용하여 자체를 비교하여 확인할 수 있습니다. ==. 파이썬이 반환됩니다 False 언제 nan 플로트는 그 자체와 비교됩니다. 예를 들어:

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

따라서 위 기능 is_number 반품을 위해 업데이트 될 수 있습니다 False ~을 위한 "NaN" 처럼:

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 요구 사항에 맞는 기능.

어떤 방법이 가장 빠른지보고 싶었습니다. 전반적으로 가장 잘하고 일관된 결과는 check_replace 기능. 가장 빠른 결과는 check_exception 기능이지만 예외가 발생하지 않은 경우에만 해고가 발생합니다. 즉, 코드가 가장 효율적이지만 예외를 던지는 오버 헤드는 상당히 큽니다.

성공적인 캐스트를 확인하는 것이 정확한 유일한 방법입니다. 예를 들어, 이것은 다음과 같이합니다. check_exception 그러나 다른 두 테스트 기능은 유효한 플로트에 대해 False를 반환합니다.

huge_number = float('1e+100')

다음은 벤치 마크 코드입니다.

import time, re, random, string

ITERATIONS = 10000000

class Timer:    
    def __enter__(self):
        self.start = time.clock()
        return self
    def __exit__(self, *args):
        self.end = time.clock()
        self.interval = self.end - self.start

def check_regexp(x):
    return re.compile("^\d*\.?\d*$").match(x) is not None

def check_replace(x):
    return x.replace('.','',1).isdigit()

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

to_check = [check_regexp, check_replace, check_exception]

print('preparing data...')
good_numbers = [
    str(random.random() / random.random()) 
    for x in range(ITERATIONS)]

bad_numbers = ['.' + x for x in good_numbers]

strings = [
    ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(random.randint(1,10)))
    for x in range(ITERATIONS)]

print('running test...')
for func in to_check:
    with Timer() as t:
        for x in good_numbers:
            res = func(x)
    print('%s with good floats: %s' % (func.__name__, t.interval))
    with Timer() as t:
        for x in bad_numbers:
            res = func(x)
    print('%s with bad floats: %s' % (func.__name__, t.interval))
    with Timer() as t:
        for x in strings:
            res = func(x)
    print('%s with strings: %s' % (func.__name__, t.interval))

2017 MacBook Pro 13에서 Python 2.7.10의 결과는 다음과 같습니다.

check_regexp with good floats: 12.688639
check_regexp with bad floats: 11.624862
check_regexp with strings: 11.349414
check_replace with good floats: 4.419841
check_replace with bad floats: 4.294909
check_replace with strings: 4.086358
check_exception with good floats: 3.276668
check_exception with bad floats: 13.843092
check_exception with strings: 15.786169

2017 MacBook Pro 13에서 Python 3.6.5의 결과는 다음과 같습니다.

check_regexp with good floats: 13.472906000000009
check_regexp with bad floats: 12.977665000000016
check_regexp with strings: 12.417542999999995
check_replace with good floats: 6.011045999999993
check_replace with bad floats: 4.849356
check_replace with strings: 4.282754000000011
check_exception with good floats: 6.039081999999979
check_exception with bad floats: 9.322753000000006
check_exception with strings: 9.952595000000002

2017 MacBook Pro 13에서 PYPY 2.7.13의 결과는 다음과 같습니다.

check_regexp with good floats: 2.693217
check_regexp with bad floats: 2.744819
check_regexp with strings: 2.532414
check_replace with good floats: 0.604367
check_replace with bad floats: 0.538169
check_replace with strings: 0.598664
check_exception with good floats: 1.944103
check_exception with bad floats: 2.449182
check_exception with strings: 2.200056

따라서 모든 것을 정리하려면 NAN, Infinity 및 복소수를 확인합니다 (I가 아닌 J, IE 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

나는 약간의 속도 테스트를했다. 문자열이 있다면 말해 봅시다 ~할 것 같은 숫자가 되려면 시도/예외 문자열이라면 전략이 가장 빠릅니다 가능성이 없습니다 숫자가 되십시오 그리고 당신은 관심이 있습니다 정수 점검, 약간의 테스트를 수행해야합니다 (IsDigit Plus '-'). 플로트 번호를 확인하려면 사용해야합니다. 시도/예외 코드 Whitout Escape.

문자열이 기본 유형 (float, int, str, bool)으로 캐스트되는지 확인해야했습니다. 인터넷에서 아무것도 찾지 못한 후 나는 이것을 만들었습니다.

def str_to_type (s):
    """ Get possible cast type for a string

    Parameters
    ----------
    s : string

    Returns
    -------
    float,int,str,bool : type
        Depending on what it can be cast to

    """    
    try:                
        f = float(s)        
        if "." not in s:
            return int
        return float
    except ValueError:
        value = s.upper()
        if value == "TRUE" or value == "FALSE":
            return bool
        return type(s)

예시

str_to_type("true") # bool
str_to_type("6.0") # float
str_to_type("6") # int
str_to_type("6abc") # str
str_to_type(u"6abc") # unicode       

유형을 캡처하고 사용할 수 있습니다

s = "6.0"
type_ = str_to_type(s) # float
f = type_(s) 

입력은 다음과 같습니다.

a="50" b=50 c=50.1 d="50.1"


1 세대 입력 :

이 기능의 입력은 모든 것이 될 수 있습니다!

주어진 변수가 숫자인지 여부를 찾습니다. 숫자 문자열은 선택적 부호, 모든 숫자, 선택적 십진수 부품 및 선택적 지수 부분으로 구성됩니다. 따라서 +0123.45E6은 유효한 숫자 값입니다. 16 진수 (예 : 0xF4C3B00C) 및 바이너리 (예 : 0B10100111001) 표기법은 허용되지 않습니다.

is_numeric 기능

import ast
import numbers              
def is_numeric(obj):
    if isinstance(obj, numbers.Number):
        return True
    elif isinstance(obj, str):
        nodes = list(ast.walk(ast.parse(obj)))[1:]
        if not isinstance(nodes[0], ast.Expr):
            return False
        if not isinstance(nodes[-1], ast.Num):
            return False
        nodes = nodes[1:-1]
        for i in range(len(nodes)):
            #if used + or - in digit :
            if i % 2 == 0:
                if not isinstance(nodes[i], ast.UnaryOp):
                    return False
            else:
                if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
                    return False
        return True
    else:
        return False

테스트:

>>> is_numeric("54")
True
>>> is_numeric("54.545")
True
>>> is_numeric("0x45")
True

is_float 기능

주어진 변수가 플로트인지 여부를 찾습니다. 플로트 문자열은 선택적 부호, 모든 숫자로 구성됩니다.

import ast

def is_float(obj):
    if isinstance(obj, float):
        return True
    if isinstance(obj, int):
        return False
    elif isinstance(obj, str):
        nodes = list(ast.walk(ast.parse(obj)))[1:]
        if not isinstance(nodes[0], ast.Expr):
            return False
        if not isinstance(nodes[-1], ast.Num):
            return False
        if not isinstance(nodes[-1].n, float):
            return False
        nodes = nodes[1:-1]
        for i in range(len(nodes)):
            if i % 2 == 0:
                if not isinstance(nodes[i], ast.UnaryOp):
                    return False
            else:
                if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
                    return False
        return True
    else:
        return False

테스트:

>>> is_float("5.4")
True
>>> is_float("5")
False
>>> is_float(5)
False
>>> is_float("5")
False
>>> is_float("+5.4")
True

무엇인가요 ast?


2- 가변 콘텐츠가 :

사용 str.isdigit () 방법

>>> a=454
>>> a.isdigit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'isdigit'
>>> a="454"
>>> a.isdigit()
True

3 수수료 입력 :

int 값 감지 :

>>> isinstance("54", int)
False
>>> isinstance(54, int)
True
>>> 

플로트 감지 :

>>> isinstance("45.1", float)
False
>>> isinstance(45.1, float)
True

Ryann은 제안합니다

NAN 및 INF에 대해 False를 반환하려면 선을 x = float로 변경하십시오. return (x == x) 및 (x -1! = x). Inf와 Nan을 제외한 모든 수레에 대해 true가 반환됩니다.

그러나 이것은 충분히 큰 수레를 위해서는 효과가 없습니다. x-1 == x 진실을 반환합니다. 예를 들어, 2.0**54 - 1 == 2.0**54

솔루션이 괜찮다고 생각합니다.

그러나,이 답변에 대해 정당화되지 않은 것으로 생각되는 Regexp 증오가 많이 있습니다. Regexps는 합리적으로 깨끗하고 정확하고 빠를 수 있습니다. 그것은 실제로 당신이하려는 일에 달려 있습니다. 원래 질문은 "문자열이 숫자 (플로트)로 표시 될 수 있는지 확인할 수있는 방법 (제목에 따라)을 어떻게 확인할 수 있는지였습니다. 아마도 유효한 것을 확인한 후에는 숫자/플로트 값을 사용하고 싶을 것입니다.이 경우 시도/제외는 많은 의미가 있습니다. 그러나 어떤 이유로 든, 당신은 a 숫자 그런 다음 Regex도 잘 작동하지만 정확 해지 기는 어렵습니다. 예를 들어, 대부분의 정규 답변은 파이썬에 관한 한 플로트 인 정수 부품 (예 : ".7")없이 문자열을 제대로 구문 분석하지 않는다고 생각합니다. 그리고 그것은 분수 부분이 필요하지 않은 단일 정규식에서 확인하기가 약간 까다 롭습니다. 나는 이것을 보여주기 위해 두 개의 동선을 포함시켰다.

"숫자"가 무엇인지에 대한 흥미로운 질문을 제기합니다. 파이썬에서 플로트로 유효한 "inf"를 포함합니까? 또는 "숫자"인 숫자를 포함하지만 파이썬으로 표시 될 수는 없습니다 (예 : 플로트 최대보다 큰 숫자).

숫자를 구문 분석하는 방법에는 모호성이 있습니다. 예를 들어, "-20"은 어떻습니까? 이것이 "숫자"입니까? 이것이 "20"을 대표하는 법적 방법입니까? Python은 "var = -20"을 수행하고 20으로 설정할 수있게 해줄 것입니다 (실제로는 표현으로 취급하기 때문), float ( "-20")는 작동하지 않습니다.

어쨌든, 더 많은 정보가 없으면 여기에 내가 믿는 모든 ints와 floats를 다루는 정규식이 있습니다. 파이썬이 그들을 구문 분석하는 것처럼.

# Doesn't properly handle floats missing the integer part, such as ".7"
SIMPLE_FLOAT_REGEXP = re.compile(r'^[-+]?[0-9]+\.?[0-9]+([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56"      # sign (-)
                            #     integer (12)
                            #           mantissa (34)
                            #                    exponent (E+56)

# Should handle all floats
FLOAT_REGEXP = re.compile(r'^[-+]?([0-9]+|[0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56"      # sign (-)
                            #     integer (12)
                            #           OR
                            #             int/mantissa (12.34)
                            #                            exponent (E+56)

def is_float(str):
  return True if FLOAT_REGEXP.match(str) else False

일부 예제 테스트 값 :

True  <- +42
True  <- +42.42
False <- +42.42.22
True  <- +42.42e22
True  <- +42.42E-22
False <- +42.42e-22.8
True  <- .42
False <- 42nope

나는 또한 당신이 언급 한 기능을 사용했지만 곧 문자열이 "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
import re
def is_number(num):
    pattern = re.compile(r'^[-+]?[-0-9]\d*\.\d*|[-+]?\.?[0-9]\d*$')
    result = pattern.match(num)
    if result:
        return True
    else:
        return False


​>>>: is_number('1')
True

>>>: is_number('111')
True

>>>: is_number('11.1')
True

>>>: is_number('-11.1')
True

>>>: is_number('inf')
False

>>>: is_number('-inf')
False

이 코드는 Regex를 사용하여 지수, 부유물 및 정수를 처리합니다.

return True if str1.lstrip('-').replace('.','',1).isdigit() or float(str1) else False

내 간단한 방법은 다음과 같습니다. 내가 일부 문자열을 통해 루프를하고 있다고 가정 해 봅시다. 숫자로 판명되면 배열에 추가하고 싶다고 가정 해 봅시다.

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

Myvar.append를 문자열로 원하는 작업으로 교체하십시오. 아이디어는 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:]), ')'

나는이 스레드로 이끌어주는 문제, 즉 데이터 모음을 가장 직관적 인 방식으로 문자열과 숫자로 변환하는 방법을 연구하고있었습니다. 원래 코드를 읽은 후 필요한 것이 두 가지 방법으로 다르다는 것을 깨달았습니다.

1- 문자열이 정수를 나타내는 경우 정수 결과를 원했습니다.

2- 데이터 구조를 고수하기 위해 숫자 또는 문자열 결과를 원했습니다.

그래서 나는이 파생물을 생성하도록 원본 코드를 조정했습니다.

def string_or_number(s):
    try:
        z = int(s)
        return z
    except ValueError:
        try:
            z = float(s)
            return z
        except ValueError:
            return s

이 시도.

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

사용자 도우미 기능 :

def if_ok(fn, string):
  try:
    return fn(string)
  except Exception as e:
    return None

그 다음에

if_ok(int, my_str) or if_ok(float, my_str) or if_ok(complex, my_str)
is_number = lambda s: any([if_ok(fn, s) for fn in (int, float, complex)])

다음을 사용하여 모든 경우를 처리합니다.

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')
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top