¿Cómo puedo verificar si una cadena es un número (float)?

votos
1k

¿Cuál es la mejor manera de verificar si una cadena se puede representar como un número en Python?

La función que tengo actualmente es:

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

Lo cual, no solo es feo y lento, parece torpe. Sin embargo, no he encontrado un método mejor porque llamar floata la función principal es aún peor.

Publicado el 09/12/2008 a las 21:03
fuente por usuario
En otros idiomas...                            


34 respuestas

votos
1k

En caso de que esté buscando números enteros (positivos, sin signo) en lugar de flotantes, puede usar la isdigit()función para objetos de cadena.

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

Métodos de cadena - isdigit()

También hay algo en las cadenas Unicode, que no estoy muy familiarizado con Unicode - Es decimal / decimal

Respondida el 09/12/2008 a las 21:15
fuente por usuario

votos
556

Lo cual, no solo es feo y lento

Yo disputaría ambos.

Un regex u otro análisis de cadenas sería más feo y lento.

No estoy seguro de que mucho podría ser más rápido que el anterior. Llama a la función y regresa. Try / Catch no introduce mucha sobrecarga porque la excepción más común se detecta sin una búsqueda exhaustiva de los fotogramas de pila.

El problema es que cualquier función de conversión numérica tiene dos tipos de resultados

  • Un número, si el número es válido
  • Un código de estado (p. Ej., Vía errno) o una excepción para mostrar que no se pudo analizar ningún número válido.

C (como un ejemplo) piratea esto de varias maneras. Python lo establece de forma clara y explícita.

Creo que tu código para hacer esto es perfecto.

Respondida el 09/12/2008 a las 21:30
fuente por usuario

votos
62

Hay una excepción que es posible que desee tener en cuenta: la cadena 'NaN'

Si quieres is_number a devolver false para 'NaN' este código no funcionará como Python lo convierte a su representación de un número que no es un número (hablar de los problemas de identidad):

>>> float('NaN')
nan

De lo contrario, en realidad se debería agradecer la pieza de código que ahora uso ampliamente. :)

GRAMO.

Respondida el 01/09/2010 a las 15:06
fuente por usuario

votos
56

TL; DR La mejor solución ess.replace('.','',1).isdigit()

Hice algunos puntos de referencia que comparan los diferentes enfoques

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

Si la cadena no es un número, el bloque excepción es bastante lento. Pero lo más importante, el try-excepto método es el único enfoque que se encarga de notación científica correctamente.

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

Notación flotar" 0.1234" no es compatible con:
- 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__)

La notación científica "1.000000e + 50" no es compatible con:
- is_number_regex
- is_number_repl_isdigit
notación científica "1E50" no es compatible con:
- is_number_regex
- is_number_repl_isdigit

EDIT: Los resultados de referencia

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

donde se probaron las siguientes funciones

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

introducir descripción de la imagen aquí

Respondida el 13/05/2014 a las 20:28
fuente por usuario

votos
51

Qué tal esto:

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

que devolverá cierto sólo si hay uno o no ''. en la cadena de dígitos.

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

devolverá falso

edit: acabo de ver otro comentario ... añadiendo una .replace(badstuff,'',maxnum_badstuff)para otros casos se puede hacer. si estás de paso de sal y condimentos no arbitraria (ref: xkcd # 974 ) esto va a hacer muy bien: P

Respondida el 25/05/2012 a las 23:22
fuente por usuario

votos
37

Actualizado después de Alfe señaló que no es necesario para comprobar la flotación separado tan complejo maneja tanto:

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

    return True

Anteriormente dijo: ¿Es algunos casos raros puede que también necesite para comprobar si los números complejos (por ejemplo, 1 + 2i), que no pueden ser representados por un flotador:

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
Respondida el 26/07/2010 a las 14:10
fuente por usuario

votos
37

Lo cual, no solo es feo y lento, parece torpe.

Puede tomar algún tiempo acostumbrarse, pero esta es la manera pitónica de hacerlo. Como ya se ha señalado, las alternativas son peores. Pero hay otra ventaja de hacer las cosas de esta manera: polimorfismo.

La idea central detrás de la tipificación de patos es que "si camina y habla como un pato, entonces es un pato". ¿Qué sucede si decide que necesita una subclase de cadena para poder cambiar la forma en que determina si algo se puede convertir en una flotación? ¿O qué pasa si decides probar algún otro objeto por completo? Puede hacer estas cosas sin tener que cambiar el código anterior.

Otros idiomas resuelven estos problemas mediante el uso de interfaces. Guardaré el análisis de qué solución es mejor para otro hilo. El punto, sin embargo, es que Python está decididamente en el lado del tipaje de tipeo de la ecuación, y es probable que tengas que acostumbrarte a la sintaxis así si planeas hacer mucha programación en Python (pero eso no significa te tiene que gustar, por supuesto).

Otra cosa que quizás desee tener en cuenta: Python es bastante rápido al lanzar y atrapar excepciones en comparación con muchos otros lenguajes (30 veces más rápido que .Net, por ejemplo). Demonios, el lenguaje en sí mismo incluso arroja excepciones para comunicar condiciones de programa normales y no excepcionales (cada vez que utiliza un bucle for). Por lo tanto, no me preocuparía demasiado por los aspectos de rendimiento de este código hasta que note un problema importante.

Respondida el 11/12/2008 a las 05:56
fuente por usuario

votos
17

Para intel uso de este:

>>> "1221323".isdigit()
True

Pero para floatque necesitamos algunos trucos ;-). Cada número flotante tiene un punto ...

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

También para los números negativos sólo tiene que añadir lstrip():

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

Y ahora tenemos un modo universal:

>>> '-12.34'.lstrip('-').replace('.','',1).isdigit()
True
>>> '.-234'.lstrip('-').replace('.','',1).isdigit()
False
Respondida el 08/09/2015 a las 08:42
fuente por usuario

votos
14

Para las cadenas de números que no son, try: except:en realidad es más lento que las expresiones regulares. Para las cadenas de números válidos, expresiones regulares es más lento. Por lo tanto, el método apropiado depende de su entrada.

Si usted encuentra que usted está en un aprieto rendimiento, puede utilizar un nuevo módulo de terceros llamados fastnumbers que proporciona una función llamada isfloat . La revelación completa, yo soy el autor. He incluido sus resultados en los tiempos siguientes.


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

  • try: except: fue rápido para la entrada numérica, pero muy lento para una entrada no válida
  • expresiones regulares es muy eficiente cuando la entrada no es válida
  • fastnumbers gana en ambos casos
Respondida el 14/08/2014 a las 04:34
fuente por usuario

votos
14

Sólo Mimic C #

En C # hay dos funciones diferentes que se encargan de analizar los valores escalares:

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

float.parse ():

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

Nota: Si usted se pregunta por qué he cambiado la excepción a una TypeError, aquí está la documentación .

float.try_parse ():

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

Nota: Usted no quiere devolver el booleano 'falso' porque eso es todavía un tipo de valor. Ninguno es mejor, ya que indica el fracaso. Por supuesto, si quieres algo diferente puede cambiar el parámetro a fallar lo que quiera.

Para extender flotador para incluir el 'parse ()' y 'try_parse ()' que necesita para monkeypatch la clase 'float' para añadir estos métodos.

Si usted quiere respetar las funciones preexistentes el código debe ser algo como:

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

Nota al margen: yo personalmente prefiero llamarlo de perforación del mono porque se siente como que estoy abusando del lenguaje cuando hago esto, pero tu caso es distinto.

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

Y la gran Sage Pythonas dijo a la Santa Sede Sharpisus, "Cualquier cosa que usted puede hacer que puedo hacerlo mejor, puedo hacer nada mejor que tú."

Respondida el 18/02/2012 a las 02:35
fuente por usuario

votos
13

Sé que esto es particularmente viejo, pero yo añadiría una respuesta Creo que cubre la información que falta de la respuesta con más votos que podría ser muy valioso para cualquiera que encontramos lo siguiente:

Para cada uno de los métodos siguientes a conectarse con una cuenta de si necesita cualquier entrada para ser aceptado. (Suponiendo que estamos utilizando las definiciones vocales de enteros en lugar de 0-255, etc.)

x.isdigit() funciona bien para comprobar si x es un entero.

x.replace('-','').isdigit() funciona bien para comprobar si x es un valor negativo (Check - in primera posición).

x.replace('.','').isdigit() funciona bien para comprobar si x es un número decimal.

x.replace(':','').isdigit() funciona bien para comprobar si x es una relación.

x.replace('/','',1).isdigit() funciona bien para comprobar si x es una fracción.

Respondida el 05/01/2016 a las 12:21
fuente por usuario

votos
10

Puede utilizar cadenas Unicode, tienen un método para hacer exactamente lo que quiere:

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

O:

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

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

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

Respondida el 04/03/2013 a las 17:12
fuente por usuario

votos
9

Lanzar para flotar y atrapar ValueError es probablemente la forma más rápida, ya que float () está destinado específicamente para eso. Cualquier otra cosa que requiera un análisis de cadenas (regex, etc.) probablemente sea más lento debido a que no está ajustado para esta operación. Mi $ 0.02.

Respondida el 09/12/2008 a las 21:31
fuente por usuario

votos
8

Digamos que tiene dígitos en cadena. str = "100949" y que le gustaría comprobar si tiene sólo números

if str.isdigit():
returns TRUE or FALSE 

docs isdigit

de lo contrario su método funciona muy bien para encontrar la ocurrencia de un dígito en una cadena.

Respondida el 13/10/2014 a las 10:17
fuente por usuario

votos
7

Quería ver cuál es el método más rápido. En general, los mejores y más consistentes resultados fueron dados por la check_replacefunción. Los resultados más rápidos fueron dadas por la check_exceptionfunción, pero sólo si no había disparado excepción - es decir, su código es el más eficiente, pero la sobrecarga de lanzar una excepción es bastante grande.

Tenga en cuenta que la comprobación de un elenco de éxito es el único método que es preciso, por ejemplo, esto funciona con check_exceptionpero las otras dos funciones de prueba devolverá False para un flotador válida:

huge_number = float('1e+100')

Aquí está el código de referencia:

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

Estos son los resultados con Python 2.7.10 en un MacBook Pro 2017 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

Estos son los resultados con Python 3.6.5 en un MacBook Pro 2017 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

Estos son los resultados con PyPy 2.7.13 en un MacBook Pro 2017 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
Respondida el 16/01/2013 a las 07:09
fuente por usuario

votos
6

Así que para poner todo junto, la comprobación de Nan, el infinito y los números complejos (parecería que se especifican con j, i no, es decir, 1 + 2j) el resultado es:

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
Respondida el 23/03/2012 a las 17:10
fuente por usuario

votos
5

Tu código se ve bien para mí.

¿Tal vez piensas que el código es "torpe" debido al uso de excepciones? Tenga en cuenta que los programadores de Python tienden a usar excepciones liberalmente cuando mejora la legibilidad del código, gracias a su baja penalización de rendimiento.

Respondida el 11/12/2008 a las 05:03
fuente por usuario

votos
4

Esta respuesta proporciona guía paso a paso que tiene una función con ejemplos para encontrar la cadena es:

  • Entero positivo
  • Positivo / negativo - número entero / flotante
  • Cómo descartar "NaN" (no un número) las cuerdas, mientras que la comprobación de número?

Compruebe si la cadena es positivo número entero

Usted puede utilizar str.isdigit()para comprobar si cadena dada es positivo entero.

Resultados de la muestra:

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

Compruebe si hay cadena como / negativo positivo - número entero / flotante

str.isdigit()devuelve Falsesi la cadena es un negativo número o un número flotante. Por ejemplo:

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

Si desea comprobar además los negativos números enteros yfloat , a continuación, puede escribir una función personalizada para comprobar 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

Ejemplo de ejecución:

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

Descartar cuerdas "NaN" (no un número), mientras que la comprobación de número

Las funciones anteriores volverán Truepara la "NAN" (No es un número) cadena porque para Python se flotación válida que representa no es un número. Por ejemplo:

>>> is_number('NaN')
True

Con el fin de comprobar si el número es "NaN", se puede utilizar math.isnan()como:

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

>>> math.isnan(nan_num)
True

O si no desea importar biblioteca adicional para comprobar esto, entonces es posible que simplemente comprobarlo vía comparándolo con sí mismo utilizando ==. Python vuelve Falseal nanflotador se compara consigo mismo. Por ejemplo:

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

Por lo tanto, por encima de la función is_numberse puede actualizar para volver Falsea"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

Ejemplo de ejecución:

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

PD: Cada operación por cada cheque en función del tipo de serie viene con una sobrecarga adicional. Seleccione la versión de is_numberla función que se adapte a sus necesidades.

Respondida el 11/02/2018 a las 05:34
fuente por usuario

votos
4

Que necesitaba para determinar si una cadena echado en tipos básicos (float, int, str, bool). Después de no encontrar nada en Internet creé esto:

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)

Ejemplo

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       

Puede capturar el tipo y utilizarlo

s = "6.0"
type_ = str_to_type(s) # float
f = type_(s) 
Respondida el 03/07/2014 a las 18:12
fuente por usuario

votos
4

Hice un poco de prueba de velocidad. Digamos que si es la cadena propensos a ser un número del try / excepto estrategia es la más rápida possible.If la cadena es poco probable que un número y que están interesados en Entero cheque, él valores a hacer alguna prueba (isdigit además del rumbo '-'). Si usted está interesado en comprobar el número de flotador, usted tiene que utilizar el try / excepto código whitout escape.

Respondida el 12/10/2010 a las 08:43
fuente por usuario

votos
3

La entrada puede ser como sigue:

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


entrada 1 General:

La entrada de esta función puede ser todo!

Encuentra si la variable dada es numérica. cadenas numéricas consisten en signo opcional, cualquier número de dígitos, parte decimal opcional y una parte exponencial opcional. Así + 0123.45e6 es un valor numérico válido. Hexadecimal (por ejemplo 0xf4c3b00c) y binario (por ejemplo 0b10100111001) notación no está permitido.

is_numeric función

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

prueba:

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

is_float función

Encuentra si la variable dada es float. flotan cuerdas consisten en signo opcional, cualquier 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

prueba:

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

lo que es ast ?


2- Si se tiene la certeza de que el contenido de la variable es de cuerdas :

uso 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érico:

detectar valor int:

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

detectar float:

>>> isinstance("45.1", float)
False
>>> isinstance(45.1, float)
True
Respondida el 06/10/2018 a las 07:23
fuente por usuario

votos
3

ryann sugiere

Si desea volver falsas para una NaN e Inf, línea de cambio en x = flotación (s); retorno (x == x) y (x - 1 = x). Esto debería devolver cierto para todos los flotadores, excepto Inf y NaN

Pero esto no funciona del todo, porque para lo suficientemente grandes flotadores, x-1 == xdevuelve verdadero. Por ejemplo,2.0**54 - 1 == 2.0**54

Respondida el 29/07/2013 a las 15:08
fuente por usuario

votos
1

También utilicé la función que usted ha mencionado, pero pronto me di cuenta de que las cadenas como "Nan", "inf" y es la variación se consideran como número. Así que propongo que mejorada versión de su función, que devolverá falsa en ese tipo de entrada y no dejará 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
Respondida el 15/10/2016 a las 18:11
fuente por usuario

votos
1

Es posible utilizar expresiones regulares.

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")
Respondida el 23/08/2015 a las 13:22
fuente por usuario

votos
1

Prueba esto.

 def is_number(var):
    try:
       if var == int(var):
            return True
    except Exception:
        return False
Respondida el 30/05/2015 a las 17:12
fuente por usuario

votos
1

Yo estaba trabajando en un problema que me llevó a este tema, a saber cómo convertir una colección de datos en cadenas y números de la forma más intuitiva. Me di cuenta después de leer el código original que lo que necesitaba era diferente de dos maneras:

1 - quería un resultado entero si la cadena representa un entero

2 - Yo quería un número o una cadena resultado para pegar en una estructura de datos

así que adaptado el código original para producir 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
Respondida el 09/11/2014 a las 14:06
fuente por usuario

votos
1

Esta es mi manera simple de hacerlo. Digamos que estoy recorriendo algunas cadenas y quiero agregarlas a una matriz si resultan ser números.

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

Reemplace el myvar.apppend con la operación que quiera hacer con la cadena si resulta ser un número. La idea es tratar de usar una operación float () y usar el error devuelto para determinar si la cadena es un número o no.

Respondida el 16/07/2009 a las 18:45
fuente por usuario

votos
1

Si desea saber si toda la cadena se puede representar como un número, querrá usar una expresión regular (o tal vez convertir el flotador a una cadena y compararlo con la cadena fuente, pero supongo que no es muy rápido). )

Respondida el 10/12/2008 a las 10:15
fuente por usuario

votos
0

Este código se ocupa de los exponentes, flotadores, y enteros, wihtout usando expresiones regulares.

return True if str1.lstrip('-').replace('.','',1).isdigit() or float(str1) else False
Respondida el 16/12/2018 a las 07:12
fuente por usuario

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
Respondida el 02/08/2018 a las 11:06
fuente por usuario

votos
0

Usar la siguiente que maneja todos los 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')
Respondida el 24/02/2017 a las 08:11
fuente por usuario

votos
0

Para comprobar si el valor de entrada es una float, puede comparar el tipo de la entrada a unafloat

def isFloat(s):
    realFloat = 0.1

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

Devoluciones:

False     # s = 5
True      # s = 1.2345

El post original en realidad volver Truea s = 5ya que es un número (entero) y se puede emitir una inta una floatsin ValueError. Si usted está tratando de verificar que se trata de un real floaten lugar de sólo un número, lo que se necesita para dar cuenta de ese caso.

Respondida el 16/09/2016 a las 02:00
fuente por usuario

votos
0

Se puede generalizar la técnica excepción de una manera útil mediante la devolución de los valores más útiles que verdadero y falso. Por ejemplo esta función pone comillas alrededor de las cadenas, pero deja números por sí solos. Que es justo lo que necesitaba para un filtro rápido y sucio a hacer algunas definiciones de variables 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:]), ')'
Respondida el 24/05/2013 a las 22:36
fuente por usuario

votos
-1

Tengo un problema similar. En lugar de definir una función ISNUMBER, Quiero convertir una lista de cadenas de flotadores, algo que en términos de alto nivel sería la siguiente:

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

Es un hecho que realmente no podemos separar el flotador (s) a partir de las funciones isFloat (s): estos dos resultados deben ser devueltos por la misma función. Además, si flotador (s) falla, todo el proceso falla, en lugar de simplemente ignorar el elemento defectuoso. Además, "0" es un número válido y debe ser incluido en la lista. Cuando el filtrado de los malos elementos, estar seguro de no excluir a 0.

Por lo tanto, la comprensión anterior se debe modificar de alguna manera:

  • si algún elemento en la lista no se puede convertir, lo ignoran y no una excepción
  • evitar llamar flotador (s) más de una vez para cada elemento (uno para la conversión, la otra para la prueba)
  • si el valor convertido es 0, que aún debe estar presente en la lista final

Propongo una solución inspirada en los tipos numéricos anulables de C #. Estos tipos están internamente representados por una estructura que tiene el valor numérico y añade un valor booleano que indica si el valor es 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]
Respondida el 17/03/2018 a las 21:18
fuente por usuario

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