validar una solo saber numeros numero letras ingreso hay float entero convertir como cadena python casting floating-point type-conversion

una - validar numero entero python



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

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

Puede tomar algún tiempo acostumbrarse, pero esta es la forma 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: el polimorfismo.

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

Otros lenguajes resuelven estos problemas usando interfaces. Guardaré el análisis de qué solución es mejor para otro hilo. Sin embargo, el punto es que python está decididamente en el lado de la ecuación al escribir pato, y probablemente tendrás que acostumbrarte a una sintaxis como esta si planeas hacer mucha programación en Python (pero eso no significa tienes que gustarte por supuesto).

Otra cosa que debería tener en cuenta: Python es bastante rápido en lanzar y capturar excepciones en comparación con muchos otros idiomas (30 veces más rápido que .Net, por ejemplo). Diablos, el lenguaje en sí mismo incluso genera excepciones para comunicar condiciones normales y no excepcionales del programa (cada vez que usa 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.

¿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 en este momento 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 a float en la función principal es aún peor.


Lo cual, no solo es feo y lento.

Yo disputaría ambos.

Una expresión regular u otro análisis de cadena sería más feo y lento.

No estoy seguro de que nada sea más rápido que lo anterior. Llama a la función y vuelve. Try / Catch no presenta mucha sobrecarga porque la excepción más común se detecta sin una búsqueda extensa de marcos 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 (por ejemplo, a través de errno) o una excepción para mostrar que no se pudo analizar un número válido.

C (como ejemplo) hacks alrededor de esto de varias maneras. Python lo expone de forma clara y explícita.

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


Solo mimic c #

En C # hay dos funciones diferentes que manejan el análisis de valores escalares:

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

float.parse ():

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

Nota: Si se está preguntando por qué cambié la excepción a un TypeError, aquí está la documentación .

float.try_parse ():

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

Nota: no desea devolver el booleano ''False'' porque sigue siendo un tipo de valor. Ninguna es mejor porque indica fracaso. Por supuesto, si quieres algo diferente, puedes cambiar el parámetro de falla a lo que quieras.

Para extender float a fin de incluir el ''parse ()'' y ''try_parse ()'' necesitarás hacer un monkeypatch en la clase ''float'' para agregar estos métodos.

Si quieres respetar las funciones preexistentes, el código debería ser algo como:

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

SideNote: Personalmente prefiero llamarlo Monkey Punching porque se siente como si estuviera abusando del lenguaje cuando hago esto, pero 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

Y el gran Sabio Pythonas dijo a la Santa Sede Sharpisus: "Todo lo que pueda hacer lo puedo hacer mejor; puedo hacer cualquier cosa mejor que usted".


Actualizado después de que Alfe señaló que no es necesario verificar la flotación por separado, ya que el complejo maneja ambos:

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

Anteriormente dijo: Es un caso raro que también necesite verificar 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


Casting to float y la captura de ValueError es probablemente la forma más rápida, ya que float () está específicamente diseñado para eso. Cualquier otra cosa que requiera análisis de cadenas (expresiones regulares, etc.) será más lenta debido al hecho de que no está sintonizada para esta operación. Mis $ 0.02.


Digamos que tienes dígitos en la cadena. str = "100949" y le gustaría verificar si solo tiene números

if str.isdigit(): returns TRUE or FALSE

documentos de isdigit

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


En caso de que esté buscando enteros de análisis (positivos, sin signo) en lugar de flotantes, puede usar la función isdigit() 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


Entonces, para ponerlo todo junto, verificando Nan, el infinito y los números complejos (parece que están especificados con j, no i, es decir, 1 + 2j) da como resultado:

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


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

  • Entero positivo
  • Positivo / negativo - entero / flotador
  • ¿Cómo descartar cadenas "NaN" (no un número) mientras se verifica el número?

Compruebe si la cadena es un entero positivo

Puede usar isdigit() para verificar si la cadena dada es un entero positivo .

Resultados de la muestra:

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

Compruebe si la cadena es positiva / negativa - entero / flotante

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

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

Si también desea verificar los enteros negativos y float , puede escribir una función personalizada para verificarlo 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

Ejecución de la muestra:

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

Deseche las cadenas "NaN" (no un número) mientras verifica el número

Las funciones anteriores devolverán True para la cadena "NAN" (no un número) porque para Python es un valor flotante válido que representa que no es un número. Por ejemplo:

>>> is_number(''NaN'') True

Para verificar si el número es "NaN", puede usar math.isnan() como:

>>> import math >>> nan_num = float(''nan'') >>> math.isnan(nan_num) True

O si no quiere importar una biblioteca adicional para verificar esto, entonces simplemente puede verificarlo comparándolo con él mismo utilizando == . Python devuelve False cuando se compara nan float consigo mismo. Por ejemplo:

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

Por lo tanto, la función anterior is_number se puede actualizar para devolver False para "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

Ejecución de la muestra:

>>> 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 operación para cada verificación, según el tipo de número, conlleva una sobrecarga adicional. Elija la versión de la función is_number que se ajuste a sus necesidades.


Hay una excepción que deberías tener en cuenta: la cadena ''NaN''

Si desea que is_number devuelva FALSE para ''NaN'', este código no funcionará ya que Python lo convierte a su representación de un número que no es un número (hable sobre los problemas de identidad):

>>> float(''NaN'') nan

De lo contrario, debería agradecerle por el código que ahora uso ampliamente. :)

SOL.


Hice alguna prueba de velocidad. Digamos que si es probable que la cadena sea un número, la estrategia try / except es la más rápida posible. Si no es probable que la cadena sea un número y usted está interesado en la verificación de enteros , vale la pena hacer una prueba (es un dígito más el encabezado ''-''). Si está interesado en verificar el número flotante, tiene que usar el código try / except whitoutoutout.


Para int use esto:

>>> "1221323".isdigit() True

Pero para float necesitamos algunos trucos ;-). Cada número de flotador tiene un punto ...

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

También para números negativos solo agrega lstrip() :

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

Y ahora conseguimos un camino universal:

>>> ''-12.34''.lstrip(''-'').replace(''.'','''',1).isdigit() True >>> ''.-234''.lstrip(''-'').replace(''.'','''',1).isdigit() False


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

Si descubre que está en un enlace de rendimiento, puede usar un nuevo módulo de terceros llamado fastnumbers que proporciona una función llamada isfloat . Revelación completa, soy el autor. He incluido sus resultados en los horarios a continuación.

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: era rápido para la entrada numérica pero muy lento para una entrada no válida
  • La expresión regular es muy eficiente cuando la entrada no es válida
  • fastnumbers gana en ambos casos

Prueba esto.

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



Qué tal esto:

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

que devolverá verdadero solo 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 ... agregando un .replace(badstuff,'''',maxnum_badstuff) para otros casos se puede hacer. Si está pasando sal y no condimentos arbitrarios (ref: xkcd#974 ) esto funcionará bien: P


Quería ver qué método es el más rápido. En general, la función check_replace proporcionó los mejores y más consistentes resultados. Los resultados más rápidos fueron dados por la función check_exception , pero solo si no hubo una excepción check_exception , lo que significa que 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 lanzamiento exitoso es el único método que es preciso, por ejemplo, esto funciona con check_exception pero las otras dos funciones de prueba devolverán False para un flotador válido:

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

Aquí están los resultados con Python 2.7.10 en un MacBook Pro 13 2017:

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

Aquí están los resultados con Python 3.6.5 en un MacBook Pro 13 2017:

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

Aquí están los resultados con PyPy 2.7.13 en un MacBook Pro 13 2017:

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


Sé que esto es particularmente antiguo, pero agregaría una respuesta que creo que cubre la información que falta en la respuesta más votada que podría ser muy valiosa para cualquiera que encuentre esto:

Para cada uno de los siguientes métodos, conéctelos con un conteo si necesita alguna entrada para ser aceptado. (Suponiendo que estamos usando definiciones vocales de enteros en lugar de 0-255, etc.)

x.isdigit() funciona bien para verificar si x es un número entero.

x.replace(''-'','''').isdigit() funciona bien para verificar si x es negativo (check - in primera posición)

x.replace(''.'','''').isdigit() funciona bien para verificar si x es un decimal.

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

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


Tu código me parece bien.

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


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

Hice algunos benchmarks comparando 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 de excepción es bastante lento. Pero lo más importante es que el método try-except es el único enfoque que maneja las notaciones científicas 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__)

La notación flotante ".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
La notación científica "1e50" no es compatible con:
- is_number_regex
- is_number_repl_isdigit

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


El uso siguiente se encarga de 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'')


La entrada puede ser la siguiente:

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

1-Entrada general:

¡La entrada de esta función puede ser todo!

Encuentra si la variable dada es numérica. Las cadenas numéricas constan de signo opcional, cualquier número de dígitos, parte decimal opcional y parte exponencial opcional. Por lo tanto, + 0123.45e6 es un valor numérico válido. No se permite la notación hexadecimal (por ejemplo, 0xf4c3b00c) y binaria (por ejemplo, 0b10100111001).

función is_numérica

import ast import number 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

función is_float

Encuentra si la variable dada es float. las cadenas flotantes constan de un 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 está seguro de que el contenido variable es String :

usar el método 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

Entrada 3-Numérica:

detectar valor int:

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

detectar flotar

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


RyanN sugiere

Si desea devolver False para un NaN e Inf, cambie la línea a x = float (s); devuelve (x == x) y (x - 1! = x). Esto debería devolver True para todos los flotadores excepto Inf y NaN.

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


Aquí está mi manera simple de hacerlo. Digamos que estoy haciendo un bucle a través de algunas cadenas y quiero agregarlas a una matriz si resultan ser números.

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

Reemplace myvar.apppend con cualquier 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.


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

1 - Quería un resultado entero si la cadena representaba un entero

2 - Quería que un número o un resultado de cadena se adhiriera a una estructura de datos

Así que adapté 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


Necesitaba determinar si una cadena se convertía 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

Puedes capturar el tipo y usarlo.

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


Puede generalizar la técnica de excepción de una manera útil devolviendo valores más útiles que Verdadero y Falso. Por ejemplo, esta función pone comillas en cadenas, pero deja números solos. Que es justo lo que necesitaba para un filtro rápido y sucio para 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:]), '')''


Si quieres saber si la cadena completa se puede representar como un número, querrás usar una expresión regular (o quizás convertir el flotante de nuevo en una cadena y compararlo con la cadena de origen, pero supongo que no es muy rápido ).


También utilicé la función que mencionaste, pero pronto noté que las cadenas como "Nan", "Inf" y su variación se consideran números. Por lo tanto, le propongo una versión mejorada de su función, que devolverá falso en ese tipo de entrada y no fallará en las 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


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