it-swarm-korea.com

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

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

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

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

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

1399
Daniel Goldberg

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

나는 둘 다 논쟁하곤했다.

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

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

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

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

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

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

608
S.Lott

Float 대신에 파싱 (양수, 부호없는) 정수를 찾고있는 경우 문자열 객체에 isdigit() function을 사용할 수 있습니다.

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

문자열 메서드 - isdigit()

유니 코드 문자열에는 뭔가 익숙하지 않습니다. 유니 코드 - 십진수/십진수입니다

1421
Zoomulator

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

문자열이 숫자가 아닌 경우 except 블록은 매우 느립니다. 하지만 더 중요한 것은 try-except 메서드가 과학 표기법을 올바르게 처리하는 유일한 방법이라는 것입니다.

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

96
Sebastian

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

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

>>> float('NaN')
nan

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

지.

66
gvrocha

이것은 어떤가요:

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

1 개 또는 2 개의 '가있는 경우에만 true를 반환합니다.' 자릿수로.

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

거짓을 반환합니다.

편집 : 방금 다른 주석을 보았습니다 ... 다른 경우에 대해 .replace(badstuff,'',maxnum_badstuff)을 추가 할 수 있습니다. 만약 당신이 소금을 넘기고 임의 조미료를 먹지 않는다면 (ref : xkcd # 974 ) 이것은 잘 될 것입니다 : P

53
haxwithaxe

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
39
Matthew Wilcoxson

추악하고 느린 것만이 아닌, 어색한 것 같습니다.

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

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

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

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

37
Jason Baker

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

그냥 모방 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;

참고 : 여전히 값 유형이므로 부울 값 'False'를 반환하지 않으려합니다. 실패를 나타내는 것이므로 아무 것도 없습니다. 물론, 다른 것을 원하면 fail 매개 변수를 원하는대로 변경할 수 있습니다.

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

기존 함수를 존중하려면 코드는 다음과 같아야합니다.

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

SideNote : 저는 개인적으로 이것을 원숭이 펀칭이라고 부릅니다. 왜냐하면 내가 YMMV를 할 때 언어를 남용하는 것처럼 느껴지기 때문입니다.

사용법 :

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

그리고 위대한 현자 파이토나스 (Sage Pythonas)는 Sharpisus 교황에게 "당신이 할 수있는 모든 일을하면 더 잘할 수 있고, 나는 당신보다 더 나은 것을 할 수 있습니다."라고 말했습니다.

15
Evan Plaice

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

성능 바인드를 발견하면 isfloat 라는 함수를 제공하는 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이 (가) 승리합니다.
15
SethMMorton

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

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

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

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

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

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

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

12
Aruthawolf

유니 코드 문자열을 사용할 수 있습니다. 원하는대로 할 수있는 방법이 있습니다.

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

또는:

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

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

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

11
Blackzafiro

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

10
codelogic

가장 빠른 방법을보고 싶었습니다. 전체적으로 check_replace 함수는 가장 일관되고 일관된 결과를 제공했습니다. 가장 빠른 결과는 check_exception 함수에 의해 제공되었지만 예외가 발생하지 않은 경우에만 해당됩니다. 즉, 코드가 가장 효율적이지만 예외를 throw하는 오버 헤드가 매우 큽니다.

예를 들어 check_exception와 함께 작동하는 경우와 같이 올바른 캐스트를 확인하는 것이 유일한 방법이지만 다른 두 테스트 함수는 유효한 float에 대해 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
9
Ron Reiter

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

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

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

주어진 문자열이 positive integer인지 확인하기 위해 str.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

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

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

따라서 위의 function is_number"NaN"as에 대해 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

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

8
Moinuddin Quadri

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

if str.isdigit():
returns TRUE or FALSE 

isdigit docs

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

7
Clayton

이 모든 것을 합치려면 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
6
a1an

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

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

5
Dubhead

문자열이 기본 유형 (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) 
4
astrodsg

나는 약간의 속도 테스트를했다. 문자열이 likely 인 경우 try/except 전략이 가장 빠릅니다. 아마도 숫자입니다 and 관심이 있습니다 정수 확인, 테스트를 해 볼 가치가 있습니다 (숫자 + '-') . 플로트 번호를 확인하려면 try/except 코드 whitout 이스케이프를 사용해야합니다.

4
FxIII

입력은 다음과 같습니다.

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


1- 일반 입력 :

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

주어진 변수가 숫자인지 여부를 찾습니다. 숫자 문자열은 선택적 기호, 임의의 자릿수, 선택적 소수 부분 및 선택적 지수 부분으로 구성됩니다. 따라서 + 0123.45e6은 유효한 숫자 값입니다. 16 진수 (예 : 0xf4c3b00c) 및 2 진수 (예 : 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 function

지정된 변수가 float인지 여부를 찾습니다. 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- 변수 내용이 String :이라는 확신이있는 경우

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

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

3
philh

또한 언급 한 기능을 사용했지만 곧 "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
1
mathfac

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:]), ')'
0
Thruston

이 시도.

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

사용자 도우미 기능 :

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)])
0
Samantha Atkins

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

0
m_eiman

나는 당신의 해결책이 좋다고 생각합니다.

그런 말로하면, 내가 생각하기에 이러한 정답에는 옳지 않은 표현이 많다. 정당화되지 않은 정규 표현식은 합리적으로 깨끗하고 정확하고 빠를 수있다. 그것은 정말로 당신이하려고하는 것에 달려 있습니다. 원래 질문은 "문자열이 숫자 (부동 소수점)로 표시 될 수 있는지 확인하는 방법"(제목 당)입니다. 예상되는 경우 숫자/float 값을 유효하다고 확인한 후에 사용해야합니다.이 경우 try/except는 많은 의미가 있습니다. 그러나 어떤 이유로, 당신은 stringis a number또한 정규 표현식 또한 잘 작동하지만 올바른 결과를 얻는 것은 어렵다)를 검증하기를 원한다면, 나는 정규 표현식의 대부분이 지금까지 해답이라고 생각합니다. 예를 들어, 파이썬에 관한 한 float 인 정수 부분 (예 : ".7")없이 문자열을 올바르게 구문 분석하지 마십시오. 그리고 소수 부분이 필요하지 않은 단일 정규식에서 확인하는 것은 약간 까다 롭습니다. 이것을 보여주기 위해 두 개의 정규식을 포함했습니다.

"숫자"가 무엇인지 흥미로운 질문을 제기합니다. 파이썬에서 float로 유효한 "inf"를 포함합니까? 또는 "숫자"이지만 파이썬에서는 표현할 수없는 숫자를 포함합니까 (예 : float max보다 큰 숫자).

숫자를 구문 분석하는 방법에는 모호함이 있습니다. 예를 들어, "- 20"은 어떻습니까? 이것은 "숫자"입니까? 이것은 "20"을 나타내는 합법적 인 방법입니까? 파이썬은 "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
0

이 코드는 정규 표현식을 사용하지 않고 지수, 부동 소수점 및 정수를 처리합니다.

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

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

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

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

0
Anil

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

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
0
user1508746
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
0
xin.chen