Como é que eu analiso um texto para um flutuador ou int em Python?

em Python, como posso processar uma cadeia numérica como "545.2222" para o seu valor flutuante correspondente, 542.2222? Ou analisar o texto "31" para um inteiro, 31?

Só quero saber como processar um carro alegórico. string a float, e (separadamente) a int string a um.

Author: Steven Vascellaro, 2008-12-19

23 answers

>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
 2142
Author: Harley Holcombe, 2008-12-19 01:54:51
def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)
 453
Author: Javier, 2014-04-08 12:20:41

Método Python para verificar se um texto é um 'float':

def is_float(value):
  try:
    float(value)
    return True
  except:
    return False

Um nome mais longo e mais preciso para esta função pode ser: is_convertible_to_float(value)

O que é, e não é um flutuador em Python pode surpreender-te:

val                   is_float(val) Note
--------------------  ----------   --------------------------------
""                    False        Blank string
"127"                 True         Passed string
True                  True         Pure sweet Truth
"True"                False        Vile contemptible lie
False                 True         So false it becomes true
"123.456"             True         Decimal
"      -127    "      True         Spaces trimmed
"\t\n12\r\n"          True         whitespace ignored
"NaN"                 True         Not a number
"NaNanananaBATMAN"    False        I am Batman
"-iNF"                True         Negative infinity
"123.E4"              True         Exponential notation
".1"                  True         mantissa only
"1,234"               False        Commas gtfo
u'\x30'               True         Unicode is fine.
"NULL"                False        Null is not special
0x3fade               True         Hexadecimal
"6e7777777777777"     True         Shrunk to infinity
"1.797693e+308"       True         This is max value
"infinity"            True         Same as inf
"infinityandBEYOND"   False        Extra characters wreck it
"12.34.56"            False        Only one dot allowed
u'四'                 False        Japanese '4' is not a float.
"#56"                 False        Pound sign
"56%"                 False        Percent of what?
"0E0"                 True         Exponential, move dot 0 places
0**0                  True         0___0  Exponentiation
"-5e-5"               True         Raise to a negative number
"+1e1"                True         Plus is OK with exponent
"+1e1^5"              False        Fancy exponent not interpreted
"+1e1.3"              False        No decimals in exponent
"-+1"                 False        Make up your mind
"(1)"                 False        Parenthesis is bad
Achas que sabes o que são números? Não és tão bom como pensas! Não é grande surpresa.
 427
Author: Eric Leschinski, 2018-08-22 17:51:07
Este é outro método que merece ser mencionado aqui, ast.literal_eval:

Isto pode ser usado para avaliar de forma segura as cadeias de caracteres que contêm expressões em Python de fontes não confiáveis sem a necessidade de analisar os próprios valores.

Isto é, uma avaliação segura.
>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
 108
Author: wim, 2012-03-15 02:23:45
float(x) if '.' in x else int(x)
 75
Author: Dino Viehland, 2008-12-19 02:33:15

Localização e vírgulas

Você deve considerar a possibilidade de vírgulas na representação de cadeia de um número, para casos como float("545,545.2222") que lança uma exceção. Em vez disso, use métodos em locale para converter as cadeias em números e interpretar vírgulas corretamente. O método locale.atof converte-se para um flutuador numa etapa, uma vez que a configuração local tenha sido definida para a Convenção de números desejada.

Exemplo 1 -- Convenções de números dos Estados Unidos

Nos Estados Unidos e no Reino Unido, vírgulas podem ser usadas como separador de milhares. Neste exemplo com o American locale, a vírgula é tratada corretamente como um separador:

>>> import locale
>>> a = u'545,545.2222'
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.atof(a)
545545.2222
>>> int(locale.atof(a))
545545
>>>

Exemplo 2 -- convenções europeias sobre números

Na maioria dos países do mundo , as vírgulas são usadas para marcas decimais em vez de períodos. Neste exemplo com o local francês, a vírgula é correctamente tratada como uma marca decimal:

>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222

O Método locale.atoi também está disponível, mas o argumento deve ser um número inteiro.

 48
Author: Mark Chackerian, 2016-04-06 23:29:46

Os utilizadores codelogic e harley estão correctos, mas tenha em mente que, se souber que a cadeia de caracteres é um inteiro (por exemplo, 545), pode chamar-se int("545") sem primeiro elenco para flutuar.

Se as suas cadeias de caracteres estão numa lista, também pode usar a função do mapa.

>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
Só é bom se forem todos do mesmo tipo.
 23
Author: Chris Cameron, 2015-03-21 08:28:35

Se não for avesso a módulos de terceiros, pode verificar o Módulo fastnumbers. Ele fornece uma função chamada fast_real que faz exatamente o que esta pergunta está pedindo e faz isso mais rápido do que uma implementação em Python puro:

>>> from fastnumbers import fast_real
>>> fast_real("545.2222")
545.2222
>>> type(fast_real("545.2222"))
float
>>> fast_real("31")
31
>>> type(fast_real("31"))
int
 22
Author: SethMMorton, 2017-08-20 02:48:49

Em Python, como posso processar uma string numérica como "545.2222" para seu valor float correspondente, 542.2222? Ou analisar a string "31" para um inteiro, 31? Eu só quero saber como processar um string flutuante para um float, e (separadamente) um string int para um int.

É bom que peças para fazer isto separadamente. Se você estiver misturando-os, você pode estar se preparando para problemas mais tarde. A resposta simples é:

"545.2222" para vírgula flutuante:

>>> float("545.2222")
545.2222

"31" para um número inteiro:

>>> int("31")
31

Outras conversões, entradas de e para cadeias de caracteres e literais:

Conversões de várias bases, e você deve saber a base com antecedência (10 é o padrão). Lembre-se que poderá prefixá-los com o que o Python espera para os seus literais (veja em baixo) ou remover o prefixo:

>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31

Se você não conhece a base com antecedência, mas você sabe que eles terão o prefixo correto, Python pode inferir isso para você se você passe 0 como base:

>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31

Literais não decimais (isto é, inteiros) de outras Bases

Se a sua motivação é ter o seu próprio código representa claramente valores específicos codificados, no entanto, pode não precisar de converter a partir das bases - pode deixar o Python fazê-lo automaticamente com a sintaxe correcta.

Pode usar os prefixos apropos para obter a conversão automática para inteiros com os seguintes literais. Estes são válidos para o Python 2 e 3:

Binário, prefixo 0b

>>> 0b11111
31

Octal, prefixo 0o

>>> 0o37
31

Hexadecimal, prefixo 0x

>>> 0x1f
31

Isto pode ser útil ao descrever as opções binárias, as permissões de ficheiros em código ou os valores do Hexadecimal para as cores - por exemplo, note no quotes:

>>> 0b10101 # binary flags
21
>>> 0o755 # read, write, execute perms for owner, read & ex for group & others
493
>>> 0xffffff # the color, white, max values for red, green, and blue
16777215

Tornando os octais Python 2 ambíguos compatíveis com o Python 3

Se vir um inteiro que começa com um 0, no Python 2, esta é a sintaxe octal (obsoleta).

>>> 037
31
É mau porque ... parece que o valor deve ser 37. Então, no Python 3, ele agora levanta um SyntaxError:
>>> 037
  File "<stdin>", line 1
    037
      ^
SyntaxError: invalid token

Converta os seus octais Python 2 para octais que funcionam tanto em 2 como em 3 com o prefixo 0o:

>>> 0o37
31
 18
Author: Aaron Hall, 2017-01-27 15:07:40
A pergunta parece um pouco velha. Mas deixe-me sugerir uma função, parseStr, que faz algo semelhante, isto é, retorna inteiro ou float e se uma determinada string ASCII não pode ser convertida para nenhum deles, ele retorna-lo intocado. O código, é claro, pode ser ajustado para fazer apenas o que você quer:
   >>> import string
   >>> parseStr = lambda x: x.isalpha() and x or x.isdigit() and \
   ...                      int(x) or x.isalnum() and x or \
   ...                      len(set(string.punctuation).intersection(x)) == 1 and \
   ...                      x.count('.') == 1 and float(x) or x
   >>> parseStr('123')
   123
   >>> parseStr('123.3')
   123.3
   >>> parseStr('3HC1')
   '3HC1'
   >>> parseStr('12.e5')
   1200000.0
   >>> parseStr('12$5')
   '12$5'
   >>> parseStr('12.2.2')
   '12.2.2'
 17
Author: krzym, 2015-03-21 08:32:25

float("545.2222") e int(float("545.2222"))

 15
Author: codelogic, 2008-12-19 01:54:11

O analisador YAML pode ajudá-lo a descobrir que tipo de dados é o seu texto. Use yaml.load(), e então você pode usar type(result) para testar o tipo:

>>> import yaml

>>> a = "545.2222"
>>> result = yaml.load(a)
>>> result
545.22220000000004
>>> type(result)
<type 'float'>

>>> b = "31"
>>> result = yaml.load(b)
>>> result
31
>>> type(result)
<type 'int'>

>>> c = "HI"
>>> result = yaml.load(c)
>>> result
'HI'
>>> type(result)
<type 'str'>
 13
Author: Rafe, 2015-03-21 08:33:48
def get_int_or_float(v):
    number_as_float = float(v)
    number_as_int = int(number_as_float)
    return number_as_int if number_as_float == number_as_int else number_as_float
 11
Author: Totoro, 2017-05-30 11:39:49

Uso Esta função para isso

import ast

def parse_str(s):
   try:
      return ast.literal_eval(str(s))
   except:
      return

Irá converter a cadeia de caracteres para o seu tipo

value = parse_str('1')  # Returns Integer
value = parse_str('1.5')  # Returns Float
 8
Author: Shameem, 2018-02-25 05:32:04

Tem de ter em conta os arredondamentos para fazer isto correctamente.

I. e. int (5.1) = > 5 int (5.6) = > 5 -- wrong, should be 6 so we do int(5.6 + 0.5) => 6

def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)
 7
Author: Nick, 2010-10-21 14:10:01
def num(s):
"""num(s)
num(3),num(3.7)-->3
num('3')-->3, num('3.7')-->3.7
num('3,700')-->ValueError
num('3a'),num('a3'),-->ValueError
num('3e4') --> 30000.0
"""
try:
    return int(s)
except ValueError:
    try:
        return float(s)
    except ValueError:
        raise ValueError('argument is not a string of number')
 7
Author: Jerry T, 2015-10-09 18:04:52

Esta é uma versão corrigida de https://stackoverflow.com/a/33017514/5973334

Isto irá tentar processar uma cadeia de caracteres e retornar int ou float dependendo do que a cadeia de caracteres representa. Pode aumentar as excepções de análise ou ter algum comportamento inesperado.

  def get_int_or_float(v):
        number_as_float = float(v)
        number_as_int = int(number_as_float)
        return number_as_int if number_as_float == number_as_int else 
        number_as_float
 3
Author: Kuzeko, 2017-05-23 11:55:19
Surpreende-me que ninguém tenha mencionado a regex porque, às vezes, as cordas têm de ser preparadas e normalizadas antes de serem colocadas no número
import re
def parseNumber(value, as_int=False):
    try:
        number = float(re.sub('[^.\-\d]', '', value))
        if as_int:
            return int(number + 0.5)
        else:
            return number
    except ValueError:
        return float('nan')  # or None if you wish

Utilização:

parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0
E já agora, algo para verificar, tem um número:
import numbers
def is_number(value):
    return isinstance(value, numbers.Number)
    # will work with int, float, long, Decimal
 3
Author: Sławomir Lenart, 2017-07-12 17:01:41

Python tem esta grande flexibilidade de análise em uma linha.

str = "545.2222"
print ("int: ", + int(float(a)))
print ("float: ", +(float(a)))
 3
Author: Harry_pb, 2018-03-01 16:32:27

Para escrever em python use as funções do construtor do tipo, passando o texto (ou qualquer que seja o valor que você está tentando lançar) como um parâmetro.

Por exemplo:

>>>float("23.333")
   23.333

Nos bastidores, o python está a chamar o método dos objectos __float__, que deverá devolver uma representação flutuante do parâmetro. Isto é especialmente poderoso, uma vez que você pode definir os seus próprios tipos (usando classes) com um método __float__ de modo que ele possa ser rodado para um carro flutuante usando o float(myobject).

 2
Author: qwerty12345, 2018-07-01 20:42:31

Utilizar:

def num(s):
    try:
        for each in s:
            yield int(each)
    except ValueError:
        yield float(each)
a = num(["123.55","345","44"])
print a.next()
print a.next()
Esta é a maneira mais Pitónica que consegui arranjar.
 1
Author: SeasonalShot, 2017-01-14 15:05:50

Utilizar:

>>> str_float = "545.2222"
>>> float(str_float)
545.2222
>>> type(_) # Check its type
<type 'float'>

>>> str_int = "31"
>>> int(str_int)
31
>>> type(_) # Check its type
<type 'int'>
 0
Author: ateymuri, 2017-01-14 15:06:15
Aqui está outra interpretação da sua pergunta (dica: é vaga). É possível que estejas à procura de algo assim.
def parseIntOrFloat( aString ):
    return eval( aString )
Funciona assim...
>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545

Teoricamente, há uma vulnerabilidade à injecção. A string poderia, por exemplo, ser "import os; os.abort()". Sem qualquer fundo sobre de onde a corda vem, entretanto, a possibilidade é especulação teórica. Uma vez que a pergunta é vaga, não é claro se essa vulnerabilidade realmente existe ou nao.
 -13
Author: S.Lott, 2015-03-21 08:30:04