programing

문자열이 숫자(플로트 또는 int)를 나타내는지 확인하려면 어떻게 해야 합니까?

padding 2023. 4. 13. 20:39
반응형

문자열이 숫자(플로트 또는 int)를 나타내는지 확인하려면 어떻게 해야 합니까?

문자열이 Python에서 숫자 값을 나타내는지 확인하려면 어떻게 해야 합니까?

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

위는 효과가 있지만 투박해 보인다.


테스트 중인 것이 사용자 입력에서 나온 경우, 이 값은 여전히 문자열입니다.int ★★★float. 입력을 숫자로 읽는 방법을 참조하십시오.입력을 변환하고, 입력이 유효한 응답을 제공할 때까지 사용자에게 입력을 요구합니다.int ★★★★★★★★★★★★★★★★★」float(일부러 '일부러')는 '일부러 '일부러'는

음수가 아닌(부호가 없는) 정수인 경우에만 다음을 사용합니다.

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

『 』의 매뉴얼:isdigit(): Python2, Python3

Python 2 Unicode 문자열의 경우:

못생기고 느릴 뿐만 아니라

난 둘 다에 이의를 제기할 거야.

regex 또는 기타 문자열 구문 분석 방식은 더 추하고 느립니다.

위보다 더 빠른 것은 없을 것 같습니다.함수를 호출하여 반환합니다.Try/Catch는 스택프레임의 광범위한 검색 없이 가장 일반적인 예외가 검출되기 때문에 오버헤드가 크지 않습니다.

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

  • 번호(숫자가 유효한 경우)
  • 유효한 번호를 구문 분석할 수 없음을 나타내는 상태 코드(예: errno) 또는 예외.

C(예를 들어)는 이 문제를 여러 가지 방법으로 회피합니다.Python은 그것을 명확하고 명확하게 표현한다.

이 일을 하기 위한 당신의 코드는 완벽하다고 생각합니다.

TL;DR 최고의 솔루션은s.replace('.','',1).isdigit()

여러 가지 접근방식을 비교하여 벤치마크를 실시했습니다.

def is_number_tryexcept(s):
    """ Returns True if string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False
       
import re    
def is_number_regex(s):
    """ Returns True if 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 if string is a number. """
    return s.replace('.','',1).isdigit()

문자열이 숫자가 아닌 경우 except-block은 매우 느립니다.그러나 더 중요한 것은 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 ('1.000000e+50'은 funcs의 f에 대해서는:'는 지원되지 않습니다:'f(scientific1)가 아닌 경우: print4\t - , f.name )

    print ('과학적 표기법 "1e50"은 funcs의 f에 대해 지원되지 않습니다: f(과학적 2)가 아닌 경우: print('\t - , f.name )

과학적 표기법 "1.000000e+50"은 다음에서 지원되지 않습니다.

  • is_number_regex
  • is_number_filength_isdigitis_number_filength_isdigit
    과학적 표기법 "1e50"은 다음에서 지원되지 않습니다.
  • is_number_regex
  • is_number_filength_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 if string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False

def is_number_regex(s):
    """ Returns True if 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 if string is a number. """
    if comp.match(s) is None:
        return s.isdigit()
    return True


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

여기에 이미지 설명 입력

고려해야 할 예외가 하나 있습니다. 문자열 'NaN'입니다.

is_number가 'NaN'에 대해 FALSE를 반환하기를 원하는 경우 Python은 이 코드를 숫자가 아닌 숫자로 변환하므로 작동하지 않습니다(ID 문제에 대해 설명).

>>> float('NaN')
nan

그렇지 않으면 현재 광범위하게 사용하고 있는 코드 조각에 대해 감사하게 생각합니다.:)

g.

이거 어때:

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

숫자 문자열에 '.'가 1개 또는 없는 경우에만 true가 반환됩니다.

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

false가 반환됩니다.

edit:코멘트가 : "하다"의 코멘트가 표시되었습니다..replace(badstuff,'',maxnum_badstuff)다른 경우에는 할 수 있습니다.임의의 조미료(ref: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은 다른 많은 언어에 비해 예외를 던지고 잡는 속도가 상당히 빠릅니다(보다 30배 빠릅니다).예를 들면, 넷).언어 자체는 예외 없는 일반 프로그램 조건(for 루프를 사용할 때마다)을 전달하기 위한 예외를 발생시킵니다.따라서 중대한 문제를 발견할 때까지 이 코드의 성능 측면에 대해 크게 걱정하지 않습니다.

★★★의 int★★★★★★★★★★★★★★★★★★:

>>> "1221323".isdigit()
True

, ★★★★★★★★★★★★★★★★★★★의 경우는,float1개의 포인트가 .모든 플로트 번호에는 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

이 답변은 다음 예시와 함께 문자열을 찾는 함수를 포함하는 단계별 가이드를 제공합니다.

  • 양의 정수
  • 양수/음수 - 정수/부동수
  • 번호를 확인하는 동안 "NaN" 문자열(숫자가 아님)을 폐기하려면 어떻게 해야 합니까?

문자열이 의 정수인지 확인합니다.

를 사용하여 지정된 문자열이 정의 정수인지 여부를 확인할 수 있습니다.

샘플 결과:

# 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

음의 정수 및 를 체크하는 경우는, 다음과 같이 커스텀 함수를 작성해 체크할 수 있습니다.

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"(숫자가 아님) 문자열의 경우 Python의 경우 숫자가 아님을 나타내는 유효한 플로트 문자열이기 때문입니다.예를 들어 다음과 같습니다.

>>> is_number('NaN')
True

번호가 "NaN"인지 확인하려면 다음과 같이 사용할 수 있습니다.

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

>>> math.isnan(nan_num)
True

다른 경우에는 Import를 사용하여 할 수 .==은 . Python을 반환한다.Falsenan플로트는 그 자체와 비교됩니다.예를 들어 다음과 같습니다.

# `nan_num` variable is taken from above example
>>> nan_num == nan_num
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니즈에 맞는 기능을 제공합니다.

아닌 , ""는 ""입니다.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:.
  • 입력이 무효일 때 regex는 매우 효율적입니다.
  • fastnumbers 승리하다

특히 오래된 질문인 것은 알지만, 투표율이 가장 높은 답변에서 누락된 정보를 포함하고 있다고 생각되는 답변을 덧붙입니다.이 답변은 이 답변에 매우 도움이 될 수 있습니다.

다음 각 메서드에 대해 허용할 입력이 필요한 경우 카운트를 사용하여 연결합니다.(0~255 등이 아닌 정수의 음성 정의를 사용하고 있다고 가정합니다.)

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

x.replace('-','').isdigit()x자리의 - position체크 - 인 퍼스트 포지션)

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

x.replace(':','').isdigit()x자리의

x.replace('/','',1).isdigit()x자리의

C# 흉내내기만 하면 됩니다.

C#에서는 스칼라 값의 해석을 처리하는 다음 두 가지 함수가 있습니다.

  • Float.Parse()
  • Float.TryParse()

float.float():

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

주의: 예외를 TypeError로 변경한 이유가 궁금하다면 다음 문서를 참조하십시오.

float.try_try():

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

참고: 부울 'False'는 여전히 값 유형이기 때문에 반환하지 않습니다.None은 장애를 나타내므로 더 낫습니다.물론 다른 것을 원하는 경우 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

Side Note:저는 개인적으로 몽키 펀칭이라고 부르는 게 더 좋아요. 왜냐하면 제가 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

위대한 세이지 파이토나스는 교황청 샤피소스에게 이렇게 말했다. "네가 할 수 있는 것은 무엇이든 내가 더 잘할 수 있고, 나는 너보다 더 잘할 수 있다."

float()는 특정 용도를 의미하기 때문에 Float()을 플로트로 캐스팅하여 ValueError를 잡는 것이 가장 빠른 방법일 수 있습니다.문자열 구문 분석(regex 등)이 필요한 다른 항목은 이 작업에 대해 조정되지 않았기 때문에 속도가 느려질 수 있습니다.제 0.02달러요

Unicode 문자열을 사용할 수 있습니다.유니코드 문자열에는 원하는 작업을 수행할 수 있는 방법이 있습니다.

>>> 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, 무한대 및 복소수(즉, 1+2j가 아닌 j로 지정되는 것으로 보입니다)를 모두 종합하면 다음과 같은 결과가 나옵니다.

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

나는 어떤 방법이 가장 빠른지 알고 싶었다.으로 가장 .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

입력은 다음과 같습니다.

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


1-일반 입력:

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

지정된 변수가 숫자인지 여부를 찾습니다.숫자 문자열은 옵션 기호, 임의 숫자, 옵션 소수점 부분 및 옵션 지수 부분으로 구성됩니다.따라서 +0123이 됩니다.45e6은 유효한 수치입니다.16진수(예: 0xf4c3b00c) 및 이진수(예: 0b1010011001) 표기법은 허용되지 않습니다.

is_filters 함수

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_filters 함수

지정된 변수가 부동 변수인지 여부를 찾습니다.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

아스트란 무엇인가?


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

가장 일반적인 플로트의 경우 정수와 소수점을 관리하고 싶습니다.을 잡읍시다"1.1"예를 들면요.

다음 중 하나를 시도합니다.

1. > Isumeric()

word = "1.1"

"".join(word.split(".")).isnumeric()
>>> True

2.> isdigit()

word = "1.1"

"".join(word.split(".")).isdigit()
>>> True

3.> isdecimal()

word = "1.1"

"".join(word.split(".")).isdecimal()
>>> True

속도:

② 상기 방법은 모두 유사한 속도를 가진다.

%timeit "".join(word.split(".")).isnumeric()
>>> 257 ns ± 12 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit "".join(word.split(".")).isdigit()
>>> 252 ns ± 11 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit "".join(word.split(".")).isdecimal()
>>> 244 ns ± 7.17 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

str.isnumeric()

True가 있는 경우, 「」는 「」입니다.False U FIFH가 포함됩니다.Unicode (((( ( U + 2155 、 VOLT FRATION ONE FIFH ) 。이 Numeric_Americ_Americ_Americ_Americ_Americ_Americada인 문자입니다.=자리, 또는 유유 = 형유형.

str.isdecimal()

True 내의 문자가 , 「」는 「」입니다.False ZERO로 숫자를 하기 위해 할 수 소수점 문자는 U+0660, 아랍어-INDIC DIGIT ZERO와 같이 10진수로 숫자를 형성하기 위해 사용할 수 있는 문자입니다.공식적으로는 10진수 문자는 유니코드 일반 범주 "Nd"의 문자입니다.

둘 다 Python 3.0의 문자열 유형에 사용할 수 있습니다.

스트링이 기본형(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) 

귀사의 솔루션은 괜찮다고 생각합니다만, regexp의 올바른 실장은 있습니다.

이러한 답변에 대해 정당하지 않다고 생각하는 많은 regexp 혐오감이 있는 것 같습니다.regexps는 합리적으로 깨끗하고 정확하고 빠르게 할 수 있습니다.당신이 무엇을 하려고 하는가에 달려있어요.당초의 질문은, 「문자열을 숫자(플로트)로 나타낼 수 있는지 어떤지」(제목대로)였습니다.유효한 것을 확인한 후에는 숫자/플로트 값을 사용하는 것이 좋습니다.이 경우 시행/제외가 매우 의미가 있습니다.그러나 어떤 이유로 문자열숫자인지 확인하려는 경우 정규식도 올바르게 작동하지만 정확한 결과를 얻기는 어렵습니다.예를 들어, 지금까지의 regex 응답의 대부분은 python에 관한 한 float인 정수 부분(예를 들어 ".7")이 없으면 문자열을 제대로 해석하지 못한다고 생각합니다.단수 부분이 필요하지 않은 단일 정규식에서는 확인하기가 조금 어렵습니다.이걸 보여주기 위해 두 개의 regex를 포함했습니다.

그것은 "숫자"가 무엇인지에 대한 흥미로운 질문을 제기합니다.python에서 float로 유효한 "inf"를 포함합니까?또는 "numbers"이지만 파이썬으로 나타낼 수 없는 숫자(예: float max보다 큰 숫자)를 포함합니까?

숫자를 해석하는 방법에도 애매모호함이 있습니다.예를 들어, "-20"은 어떻습니까?이게 숫자인가요?이것이 "20"을 표현하는 합법적인 방법인가요?Python은 "var = --20"을 허용하고 20으로 설정합니다(이것은 표현식으로 취급하기 때문이지만, float(float)--20")는 작동하지 않습니다.

어쨌든, 더 많은 정보 없이, 여기 모든 ints와 floats를 포함하는 python이 해석하는 것처럼 보이는 regex가 있습니다.

# 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

@ron-reiter의 답변에서 벤치마킹코드를 실행하면 이 regex가 실제로 일반 regex보다 빠르고 잘못된 값을 처리하는 속도가 예외보다 훨씬 빠르다는 것을 알 수 있습니다.이것은 어느 정도 의미가 있습니다.결과:

check_regexp with good floats: 18.001921
check_regexp with bad floats: 17.861423
check_regexp with strings: 17.558862
check_correct_regexp with good floats: 11.04428
check_correct_regexp with bad floats: 8.71211
check_correct_regexp with strings: 8.144161
check_replace with good floats: 6.020597
check_replace with bad floats: 5.343049
check_replace with strings: 5.091642
check_exception with good floats: 5.201605
check_exception with bad floats: 23.921864
check_exception with strings: 23.755481

속도 테스트를 좀 해봤어요.문자열이 숫자일 가능성이 높은 경우 시행/제외 전략이 가장 빠릅니다.문자열이 숫자가 아닐 가능성이 높고 Integer Check에 관심이 있는 경우 테스트를 수행할 필요가 있습니다(isdigit + heading '-').플로트 번호를 확인하려면 try/except code whitout escape를 사용해야 합니다.

RyanN은 제안합니다.

NaN 및 Inf에 대해 False를 반환하려면 라인을 x = float(s)로 변경하고 반환(x == x) 및 (x - 1!= x)로 변경합니다.Inf 및 NaN을 제외한 모든 플로트에 대해 True가 반환됩니다.

하지만 이건 별로 효과가 없어요. 왜냐하면 충분히 큰 부표라면x-1 == xtrue가 됩니다.를 들어, 「」라고 하는 것은,2.0**54 - 1 == 2.0**54

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

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

이 코드는 정규식을 사용하여 지수, 플로트 및 정수를 처리합니다.

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() 연산을 사용하여 반환된 오류를 사용하여 문자열이 숫자인지 여부를 판단합니다.

말씀하신 기능도 사용하고 있습니다만, 얼마 지나지 않아 문자열이 「Nan」 「Inf」 「Variation」로 되어 있는 것을 알 수 있습니다.따라서 이러한 유형의 입력에 대해 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

사용자 도우미 기능:

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)])
def is_float(s):
    if s is None:
        return False

    if len(s) == 0:
        return False

    digits_count = 0
    dots_count = 0
    signs_count = 0

    for c in s:
        if '0' <= c <= '9':
            digits_count += 1
        elif c == '.':
            dots_count += 1
        elif c == '-' or c == '+':
            signs_count += 1
        else:
            return False

    if digits_count == 0:
        return False

    if dots_count > 1:
        return False

    if signs_count > 1:
        return False

    return True

언급URL : https://stackoverflow.com/questions/354038/how-do-i-check-if-a-string-represents-a-number-float-or-int

반응형