Como posso verificar se uma string é um número (float)?

votos
1k

Qual é a melhor maneira possível para verificar se uma string pode ser representado como um número em Python?

A função atualmente eu tenho agora é:

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

Que, não só é feio e lento, parece desajeitado. No entanto, eu não encontrei um método melhor, porque chamar floatna função principal é ainda pior.

Publicado 09/12/2008 em 21:03
fonte usuário
Em outras línguas...                            


36 respostas

votos
1k

No caso de você está procurando analisar inteiros (positivos, não assinados) em vez de carros alegóricos, você pode usar a isdigit()função para objetos string.

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

Métodos String - isdigit()

Há também algo sobre cadeias de caracteres Unicode, que eu não estou muito familiarizado com Unicode - É decimal / decimal

Respondeu 09/12/2008 em 21:15
fonte usuário

votos
556

Que, não só é feio e lento

Eu disputar ambos.

A regex ou outra análise de cadeia seria mais feio e mais lento.

Eu não tenho certeza que muita coisa poderia ser mais rápido do que o anterior. Ele chama a função e retorna. Try / catch não introduz muita sobrecarga porque a exceção mais comum é pego sem uma extensa pesquisa de quadros de pilha.

A questão é que qualquer função de conversão numérica tem dois tipos de resultados

  • Um número, se o número é válido
  • Um código de estado (por exemplo, através de errno) ou excepção para mostrar que nenhum número válido pôde ser analisado.

C (como um exemplo) corta em torno deste um número de maneiras. Python coloca-lo de forma clara e explicitamente.

Eu acho que o seu código para fazer isso é perfeito.

Respondeu 09/12/2008 em 21:30
fonte usuário

votos
62

Há uma exceção que você pode querer ter em conta: a string 'NaN'

Se você quiser is_number para retornar FALSE para 'NaN' este código não funcionará como Python converte em sua representação de um número que não é um número (falar sobre questões de identidade):

>>> float('NaN')
nan

Caso contrário, eu realmente deveria agradecer o pedaço de código que eu agora usar extensivamente. :)

G.

Respondeu 01/09/2010 em 15:06
fonte usuário

votos
56

TL; DR A melhor solução és.replace('.','',1).isdigit()

Eu fiz alguns benchmarks comparando as diferentes abordagens

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

Se a cadeia não é um número, o bloco exceção é bastante lento. Mas o mais importante, o try-excepto método é a única abordagem que lida com Notação Científica corretamente.

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

Notação Float" 0,1234" não é suportado por:
- 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__)

Notação científica "1.000000e + 50" não é suportado por:
- is_number_regex
- is_number_repl_isdigit
notação científica "1e50" não é suportado por:
- is_number_regex
- is_number_repl_isdigit

EDIT: Os resultados do benchmark

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

onde as funções seguintes foram testados

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

digite descrição da imagem aqui

Respondeu 13/05/2014 em 20:28
fonte usuário

votos
51

que tal agora:

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

que retornará verdadeiro somente se houver um ou nenhum '' na seqüência de dígitos.

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

retornará false

Edit: Só vi outro comentário ... adicionando uma .replace(badstuff,'',maxnum_badstuff)para outros casos pode ser feito. se você estiver passando sal e não arbitrária condimentos (ref: xkcd # 974 ) isso vai fazer muito bem: P

Respondeu 25/05/2012 em 23:22
fonte usuário

votos
37

Atualizado após Alfe apontou você não precisa verificar se há flutuador separadamente como complexo lida com ambos:

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

    return True

Anteriormente disse: É alguns casos raros, você também pode precisar verificar se há números complexos (por exemplo, 1 + 2i), que não podem ser representados por um float:

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
Respondeu 26/07/2010 em 14:10
fonte usuário

votos
37

Que, não só é feio e lento, parece desajeitado.

Pode levar algum tempo para se acostumar, mas esta é a maneira Python de fazê-lo. Como já foi referido, as alternativas são piores. Mas há uma outra vantagem de fazer as coisas desta maneira: polimorfismo.

A idéia central por trás tipagem pato é que "se ele anda e fala como um pato, então é um pato." E se você decidir que você precisa para subclasse seqüência de modo que você pode mudar a forma como você determinar se algo pode ser convertida em uma bóia? Ou que se você decidir testar algum outro objeto inteiramente? Você pode fazer essas coisas sem ter que mudar o código acima.

Outros idiomas resolver esses problemas usando interfaces. Vou guardar a análise de qual solução é melhor para outro segmento. A questão, porém, é que python é decididamente no lado do pato digitação da equação, e você provavelmente vai ter que se acostumar a sintaxe como esta, se você planeja fazer muita programação em Python (mas isso não significa você tem que gostar dele, claro).

Uma outra coisa que você pode querer tomar em consideração: Python é muito rápido em jogar e pegar exceções em comparação com um monte de outras línguas (30x mais rápido do que .Net por exemplo). Heck, a linguagem em si mesmo gera exceções para se comunicar não-excepcionais, as condições do programa normal (cada vez que você usar um loop). Assim, eu não me preocuparia muito com os aspectos de desempenho deste código até que você observe um problema significativo.

Respondeu 11/12/2008 em 05:56
fonte usuário

votos
17

Para intuso isso:

>>> "1221323".isdigit()
True

Mas para floatnós precisamos alguns truques ;-). Cada número flutuador possui um ponto ...

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

Também para números negativos basta adicionar lstrip():

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

E agora temos uma maneira universal:

>>> '-12.34'.lstrip('-').replace('.','',1).isdigit()
True
>>> '.-234'.lstrip('-').replace('.','',1).isdigit()
False
Respondeu 08/09/2015 em 08:42
fonte usuário

votos
14

Para strings de não-números, try: except:é realmente mais lento do que expressões regulares. Para seqüências de números válidos, regex é mais lento. Assim, o método adequado depende de sua entrada.

Se você achar que você está em um ligamento desempenho, você pode usar um novo módulo de terceiros chamados fastnumbers que fornece uma função chamada isfloat . A divulgação completa, eu sou o autor. Eu incluí seus resultados nos horários abaixo.


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

Como você pode ver

  • try: except: foi rápido para entrada numérica, mas muito lento para uma entrada inválida
  • regex é muito eficiente quando a entrada é inválido
  • fastnumbers ganha em ambos os casos
Respondeu 14/08/2014 em 04:34
fonte usuário

votos
14

Apenas Mimic C #

Em C # existem duas funções diferentes que lidam com a análise dos valores escalares:

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

float.parse ():

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

Nota: Se você está se perguntando por que eu mudei a exceção para um TypeError, aqui está a documentação .

float.try_parse ():

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

Nota: Você não quer retornar o booleano 'False' porque isso é ainda um tipo de valor. Nenhum é melhor porque indica falha. Claro, se você quiser algo diferente, você pode alterar o parâmetro não conseguem o que quiser.

Para estender flutuador incluir o 'parse ()' e 'try_parse ()' você precisa monkeypatch a classe 'float' para adicionar esses métodos.

Se você quiser respeitar funções pré-existentes o código deve ser algo como:

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

SideNote: Eu pessoalmente prefiro chamá-lo de macaco Punching porque parece que estou abusando da linguagem quando eu faço isso, mas YMMV.

Uso:

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

E o grande sábio Pythonas disse à Santa Sé Sharpisus, "Qualquer coisa que você pode fazer Eu posso fazer melhor, eu posso fazer qualquer coisa melhor do que você."

Respondeu 18/02/2012 em 02:35
fonte usuário

votos
13

Eu sei que isto é particularmente velho, mas eu gostaria de acrescentar uma resposta Acredito que cobre a informação em falta a partir do mais votado resposta que poderia ser muito valioso para qualquer um que encontrar este:

Para cada um dos seguintes métodos conectá-los com uma contagem, se você precisar de qualquer entrada para ser aceite. (Supondo que estamos usando definições vocais de inteiros em vez de 0-255, etc.)

x.isdigit() funciona bem para verificar se x é um inteiro.

x.replace('-','').isdigit() funciona bem para verificar se x é um negativo (Confira - na primeira posição).

x.replace('.','').isdigit() funciona bem para verificar se x é um decimal.

x.replace(':','').isdigit() funciona bem para verificar se x é uma relação.

x.replace('/','',1).isdigit() funciona bem para verificar se x é uma fração.

Respondeu 05/01/2016 em 15:21
fonte usuário

votos
10

Você pode usar cadeias de caracteres Unicode, eles têm um método para fazer exatamente o que você quer:

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

Ou:

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

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

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

Respondeu 04/03/2013 em 17:12
fonte usuário

votos
9

A projeção para flutuar e captura ValueError é provavelmente a maneira mais rápida, uma vez float () é especificamente destinado para isso. Qualquer outra coisa que requer seqüência de análise (regex, etc) provavelmente será mais lento devido ao fato de que ele não está sintonizado para esta operação. Minha US $ 0,02.

Respondeu 09/12/2008 em 21:31
fonte usuário

votos
8

Vamos dizer que você tem dígitos em string. str = "100949" e que você gostaria de verificar se ele tem apenas números

if str.isdigit():
returns TRUE or FALSE 

docs isdigit

caso contrário, seu método funciona muito bem para encontrar a ocorrência de um dígito em uma string.

Respondeu 13/10/2014 em 10:17
fonte usuário

votos
7

Eu queria ver qual método é mais rápido. Em geral, os melhores e mais consistentes resultados foram dadas pelo check_replacefunção. Os resultados mais rápidos foram dadas pelo check_exceptionfunção, mas apenas se não houvesse nenhuma exceção disparado - o que significa que seu código é o mais eficiente, mas a sobrecarga de lançar uma exceção é bastante grande.

Por favor note que a verificação de um elenco bem sucedido é o único método que é preciso, por exemplo, isso funciona com check_exception, mas as outras duas funções de teste retornará False para um flutuador válido:

huge_number = float('1e+100')

Aqui está o código de referência:

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

Aqui estão os resultados com Python 2.7.10 em um 2017 MacBook Pro 13:

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

Aqui estão os resultados com Python 3.6.5 em um 2017 MacBook Pro 13:

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

Aqui estão os resultados com PyPy 2.7.13 em um 2017 MacBook Pro 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
Respondeu 16/01/2013 em 07:09
fonte usuário

votos
6

Então, para colocá-lo todos juntos, a verificação de Nan, infinito e números complexos (parece que eles são especificados com j, não eu, ou seja, 1 + 2j) resulta em:

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
Respondeu 23/03/2012 em 17:10
fonte usuário

votos
5

Seu código parece-me muito bem.

Talvez você acha que o código é "desajeitado" por causa do uso de exceções? Note-se que os programadores Python tendem a usar exceções liberalmente quando melhora a legibilidade do código, graças à sua penalidade de baixo desempenho.

Respondeu 11/12/2008 em 05:03
fonte usuário

votos
4

Esta resposta fornece guia passo a passo tendo função com exemplos de encontrar a string é:

  • inteiro positivo
  • Positivo / negativo - inteiro / float
  • Como descartar "NaN" (não um número) cordas durante a verificação de número?

Verifica se o texto é positivo inteiro

Você pode usar str.isdigit()para verificar se determinada string é positivo inteiro.

Resultados da Amostra:

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

Verifique para string como positivo / negativo - inteiro / float

str.isdigit()retorna Falsese a cadeia é um negativo número ou um número float. Por exemplo:

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

Se você quiser verificar também para os negativos inteiros efloat , em seguida, você pode escrever uma função personalizada para verificar se há-lo como:

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

Amostra Run:

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

Descarte "NaN" (não um número) cordas durante a verificação de número

As funções acima voltará Truepara a cadeia porque para Python "NAN" (não um número) é flutuante válido representando não é um número. Por exemplo:

>>> is_number('NaN')
True

A fim de verificar se o número é "NaN", você pode usar math.isnan()como:

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

>>> math.isnan(nan_num)
True

Ou se você não quiser importar biblioteca adicional de verificar isso, então você pode simplesmente verificar se via comparando-a com a própria usando ==. Python retorna Falsequando nanflutuador é comparado com ele mesmo. Por exemplo:

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

Por isso, acima de função is_numberpode ser atualizado para voltar Falsepara"NaN" como:

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

Amostra Run:

>>> 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: Cada operação para cada controlo, dependendo do tipo de número vem com uma sobrecarga adicional. Escolha a versão de is_numberfunção que se adapta à sua exigência.

Respondeu 11/02/2018 em 08:34
fonte usuário

votos
4

Eu precisava determinar se uma corda lançada tipos básicos (float, int, str, bool). Depois de não encontrar qualquer coisa na internet que eu criei esta:

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)

Exemplo

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       

Você pode capturar o tipo e usá-lo

s = "6.0"
type_ = str_to_type(s) # float
f = type_(s) 
Respondeu 03/07/2014 em 18:12
fonte usuário

votos
4

Eu fiz alguns testes de velocidade. Vamos dizer que se a cadeia é provável a ser um número a try / exceto estratégia é a possible.If mais rápido a corda é pouco provável a ser um número e você está interessado em Integer cheque, valha a pena fazer algum teste (isdigit mais dirigindo '-'). Se você estiver interessado em verificar o número de float, você tem que usar o try / exceto código whitout fuga.

Respondeu 12/10/2010 em 08:43
fonte usuário

votos
3

A entrada pode ser a seguinte:

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


entrada 1 Geral:

A entrada desta função pode ser tudo!

Verifica se uma dada variável é numérico. cordas numéricos consistem de sinal opcional, qualquer número de dígitos, parte decimal opcional e parte exponencial opcional. Assim + 0123.45e6 é um valor numérico válido. Hexadecimal (por exemplo 0xf4c3b00c) e binário (por exemplo 0b10100111001) notação não é permitido.

is_numeric função

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

teste:

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

is_float função

Verifica se uma dada variável é float. flutuar cordas consistem de sinal opcional, qualquer número de dígitos, ...

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

teste:

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

o que é ast ?


2 Se você estiver confiante de que o conteúdo variável é string :

utilização str.isdigit () Método

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

entrada 3-numérica:

detectar valor int:

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

detectar float:

>>> isinstance("45.1", float)
False
>>> isinstance(45.1, float)
True
Respondeu 06/10/2018 em 07:23
fonte usuário

votos
3

Ryann sugere

Se você quiser retornar False para um NaN e Inf, linha mudança x = float (s); return (x == x) e (x - 1 = x). Isso deve retornar verdadeiro para todos os carros alegóricos, exceto Inf e NaN

Mas isso não funciona muito bem, porque para suficientemente grandes carros alegóricos, x-1 == xretorna true. Por exemplo,2.0**54 - 1 == 2.0**54

Respondeu 29/07/2013 em 15:08
fonte usuário

votos
1

Também usei a função que você mencionou, mas logo percebo que strings como "Nan", "Inf" e é variações são consideradas como número. Assim, proponho que você versão melhorada de sua função, que irá retornar falso sobre aqueles tipo de entrada e não deixará variantes "1E3":

def is_float(text):
    try:
        float(text)
        # check for nan/infinity etc.
        if text.isalpha():
            return False
        return True
    except ValueError:
        return False
Respondeu 15/10/2016 em 21:11
fonte usuário

votos
1

Você pode usar regex.

number = raw_input("Enter a number: ")
if re.match(r'^\d+$', number):
    print "It's integer"
    print int(number)
elif re.match(r'^\d+\.\d+$', number):
    print "It's float"
    print float(number)
else:
    print("Please enter a number")
Respondeu 23/08/2015 em 13:22
fonte usuário

votos
1

Tente isto.

 def is_number(var):
    try:
       if var == int(var):
            return True
    except Exception:
        return False
Respondeu 30/05/2015 em 17:12
fonte usuário

votos
1

Eu estava trabalhando em um problema que me levou a esta discussão, a saber como converter um conjunto de dados para cordas e números da forma mais intuitiva. Percebi depois de ler o código original que o que eu precisava era diferente de duas maneiras:

1 - Eu queria um resultado inteiro se a string representado um inteiro

2 - Eu queria um número ou uma string de resultado para ficar em uma estrutura de dados

por isso adaptado o código original para produzir este derivado:

def string_or_number(s):
    try:
        z = int(s)
        return z
    except ValueError:
        try:
            z = float(s)
            return z
        except ValueError:
            return s
Respondeu 09/11/2014 em 14:06
fonte usuário

votos
1

Aqui está a minha maneira simples de fazê-lo. Vamos dizer que eu estou looping através de algumas cordas e eu quero adicioná-los para uma matriz, se eles acabam por ser números.

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

Substitua o myvar.apppend com qualquer operação que você quer fazer com a corda se ele sair para ser um número. A idéia é tentar utilizar uma operação float () e usar o erro retornado para determinar se ou não a string é um número.

Respondeu 16/07/2009 em 18:45
fonte usuário

votos
1

Se você quer saber se a toda corda pode ser representado como um número que você vai querer usar uma expressão regular (ou talvez converter a flutuação de costas em uma string e compará-la com a cadeia de origem, mas eu estou supondo que não é muito rápido ).

Respondeu 10/12/2008 em 10:15
fonte usuário

votos
0

função auxiliar de usuário:

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

então

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)])
Respondeu 16/08/2019 em 01:18
fonte usuário

votos
0

Eu acho que a solução está bem.

Dito isto, há um monte de ódio regexp para estas respostas que eu acho que não é justificada, regexps pode ser razoavelmente limpo e correto e rápido. Ela realmente depende do que você está tentando fazer. A pergunta original era como você pode "verificar se uma string pode ser representado como um número (float)" (de acordo com o seu título). Provavelmente, você iria querer usar o valor numérico / float Depois de ter verificado que é válido, caso em que o seu try / exceto faz muito sentido. Mas se, por algum motivo, você quiser apenas para validar que a corda é um número , em seguida, um regex também funciona bem, mas é difícil para obter correta. Eu acho que a maioria das respostas regex até agora, por exemplo, não analisar corretamente cordas sem uma parte inteira (como" 0,7" ), que é um float, tanto quanto python está em causa. E isso é um pouco complicado para verificar em um único regex onde a porção fracionária não é necessária. Eu incluí dois regex para mostrar isso.

Ele faz levantar a questão interessante sobre o que um "número" é. Você incluir "inf", que é válido como uma bóia em python? Ou você incluir números que são "números" mas talvez não pode ser representado em python (como números que são maiores do que o flutuador max).

Há também ambiguidades na forma como você analisar números. Por exemplo, o que acontece "--20"? É este um "número"? Será esta uma forma legal para representar "20"? Python vai deixar você fazer "var = --20" e configurá-lo para 20 (embora realmente isso é porque ele trata como uma expressão), mas float ( "- 20") não funciona.

De qualquer forma, sem mais informações, aqui está um regex que eu acredito que abrange todos os ints e flutua como python analisa-los .

# 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

Alguns valores de ensaio exemplo:

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
Respondeu 11/05/2019 em 00:15
fonte usuário

votos
0

Este código lida com os expoentes, carros alegóricos, e inteiros, wihtout usando regex.

return True if str1.lstrip('-').replace('.','',1).isdigit() or float(str1) else False
Respondeu 16/12/2018 em 07:12
fonte usuário

votos
0
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
Respondeu 02/08/2018 em 11:06
fonte usuário

votos
0

usar seguinte ele lida com todos os casos: -

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')
Respondeu 24/02/2017 em 11:11
fonte usuário

votos
0

Para verificar se o valor de entrada é um float, você pode comparar o tipo de entrada para umfloat

def isFloat(s):
    realFloat = 0.1

    if type(s) == type(realFloat):
        return True
    else:
        return False

retorna:

False     # s = 5
True      # s = 1.2345

O post original seria realmente voltar Truepara s = 5uma vez que é um número (inteiro) e você pode lançar um inta um floatsem ValueError. Se você está tentando verificar se ele é um real float, em vez de apenas um número, você precisa explicar esse caso.

Respondeu 16/09/2016 em 05:00
fonte usuário

votos
0

Você pode generalizar a técnica exceção de uma maneira útil, retornando valores mais útil do Verdadeiro e Falso. Por exemplo esta função coloca aspas rodada cordas, mas deixa os números sozinho. Que é apenas o que eu precisava para um filtro rápido e sujo para fazer algumas definições variáveis ​​para 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:]), ')'
Respondeu 24/05/2013 em 22:36
fonte usuário

votos
-1

Eu tenho um problema similar. Em vez de definir uma função ISNUMBER, eu quero converter uma lista de strings que flutua, algo que em termos de alto nível seria:

[ float(s) for s in list if isFloat(s)]

É um dado que não pode realmente separar o flutuador (s) das funções isFloat (s): estes dois resultados devem ser devolvidos pela mesma função. Além disso, se float (s) falhar, todo o processo falhar, em vez de simplesmente ignorar o elemento defeituoso. Além disso, "0" é um número válido e deve ser incluído na lista. Quando filtrando maus elementos, a certeza de não excluir 0.

Portanto, a compreensão acima deve ser modificada de alguma forma:

  • se algum elemento da lista não pode ser convertido, ignorá-lo e não lançar uma exceção
  • evitar a chamada flutuador (s) mais de uma vez por cada elemento (uma para a conversão, a outra para o teste)
  • se o valor convertido é 0, ele ainda deve estar presente na lista final

Proponho uma solução inspirada nos tipos numéricos anuláveis ​​de C #. Estes tipos são internamente representado por uma estrutura que tem o valor numérico e adiciona um booleano que indica se o valor é válido:

def tryParseFloat(s):
    try:
        return(float(s), True)
    except:
        return(None, False)

tupleList = [tryParseFloat(x) for x in list]
floats = [v for v,b in tupleList if b]
Respondeu 18/03/2018 em 00:18
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more