Comment puis-je analyser une chaîne à un float ou à un int en Python?

en Python, Comment puis-je analyser une chaîne numérique comme "545.2222" à sa valeur flottante correspondante, 542.2222 ? Ou analyser la chaîne "31" à un entier, 31 ?

je veux juste savoir comment analyser un float string à un float , et (séparément) un int string à une int .

1821
demandé sur Steven Vascellaro 2008-12-19 04:52:26

23 réponses

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

méthode Python pour vérifier si une chaîne est un flotteur:

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

un nom plus long et plus précis pour cette fonction pourrait être: is_convertible_to_float(value)

Ce qui est, et n'est pas un flotteur dans Python peut-être vous surprendre:

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

vous pensez savoir ce que sont les nombres? Vous n'êtes pas aussi bon que vous le pensez! Pas de grosse surprise.

427
répondu Eric Leschinski 2018-08-22 17:51:07

c'est une autre méthode qui mérite d'être mentionnée ici, ast.littéral_eval :

ceci peut être utilisé pour évaluer en toute sécurité des chaînes contenant des expressions Python de sources non fiables sans avoir à analyser les valeurs soi-même.

C'est-à-dire une "évaluation" sûre 151940920"

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
108
répondu wim 2012-03-15 02:23:45
float(x) if '.' in x else int(x)
75
répondu Dino Viehland 2008-12-19 02:33:15

localisation et virgules

vous devriez considérer la possibilité de virgules dans la représentation de chaîne d'un nombre, pour des cas comme float("545,545.2222") qui jette une exception. Utilisez plutôt les méthodes de locale pour convertir les chaînes en nombres et interpréter correctement les virgules. La méthode locale.atof convertit en un flottant en une étape une fois que la locale a été définie pour la convention de nombre désirée.

Exemple 1 -- United États nombre conventions

aux États-Unis et au Royaume-Uni, les virgules peuvent être utilisées comme séparateur de milliers. Dans cet exemple avec American locale, la virgule est traitée correctement comme un séparateur:

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

exemple 2 -- conventions du numéro européen

"

dans le la majorité des pays du monde , les virgules sont utilisées pour les marques décimales au lieu des périodes. Dans cet exemple avec LA locale FRANÇAISE, la virgule est correctement traitée comme une marque décimale:

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

La méthode locale.atoi est également disponible, mais l'argument doit être un nombre entier.

48
répondu Mark Chackerian 2016-04-06 23:29:46

Utilisateurs codelogic et harley sont correctes, mais gardez à l'esprit si vous connaissez la chaîne est un nombre entier (par exemple, 545), vous pouvez appeler int("545") sans premier casting de flotter.

Si vos cordes sont dans une liste, vous pouvez utiliser la fonction map.

>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>

ce n'est bon que s'ils sont tous du même type.

23
répondu Chris Cameron 2015-03-21 08:28:35

si vous n'êtes pas contre les modules tiers, vous pouvez consulter le module fastnumber . Il fournit une fonction appelée fast_real qui fait exactement ce que cette question demande et le fait plus rapidement qu'une implémentation pure-Python:

>>> 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
répondu SethMMorton 2017-08-20 02:48:49

en Python, Comment puis-je analyser une chaîne numérique comme "545.2222" à sa valeur flottante correspondante, 542.2222? Ou parse la chaîne "31" à un entier, 31? Je veux juste savoir comment analyser une chaîne de flotteurs en flotteurs, et (séparément) une chaîne int en int.

il est bon que vous demandiez de les faire séparément. Si vous les mélangez, vous pourriez vous préparer à des problèmes plus tard. La réponse est simple:

"545.2222" pour flotter:

>>> float("545.2222")
545.2222

"31" à un entier:

>>> int("31")
31

autres conversions, en et à partir de cordes et littérales:

Conversions à partir de différentes bases, et vous devriez connaître la base à l'avance (10 est la valeur par défaut). Notez que vous pouvez les préfixer avec ce que Python attend pour ses littérales (voir ci-dessous) ou supprimer le préfixe:

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

si vous ne connaissez pas la base à l'avance, mais vous savez qu'ils auront le bon préfixe, Python peut inférer cela pour vous si vous passez 0 comme base:

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

littérales Non décimales (C'est-à-dire entières) à partir d'autres Bases

si votre motivation est d'avoir votre propre code représente clairement des valeurs spécifiques codées, cependant, vous pouvez ne pas avoir besoin de convertir à partir des bases - vous pouvez laisser Python le fait pour vous automatiquement avec la syntaxe correcte.

vous pouvez utiliser les préfixes apropos pour obtenir la conversion automatique en entiers avec les littérales suivantes . Ceux-ci sont valables pour Python 2 et 3:

binaire, préfixe 0b

>>> 0b11111
31

Octal, préfixe 0o

>>> 0o37
31

hexadécimal, préfixe 0x

>>> 0x1f
31

cela peut être utile pour décrire des drapeaux binaires, des permissions de fichiers en code, ou des valeurs hexadécimales pour les couleurs - par exemple, notez pas de guillemets:

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

Faire ambigu Python 2 octals compatible avec Python 3

si vous voyez un entier qui commence par un 0, en Python 2, c'est la syntaxe octale (dépréciée).

>>> 037
31

il est mauvais parce qu'il ressemble à la valeur devrait être 37 . Donc en Python 3, Il soulève maintenant un SyntaxError :

>>> 037
  File "<stdin>", line 1
    037
      ^
SyntaxError: invalid token

Convertissez vos octals Python 2 en octals qui fonctionnent en 2 et 3 avec le préfixe 0o :

>>> 0o37
31
18
répondu Aaron Hall 2017-01-27 15:07:40

la question semble un peu vieille. Mais permettez-moi de Suggérer une fonction, parseStr, qui fait quelque chose de similaire, c'est-à-dire retourne entier ou flotter et si une chaîne ASCII donnée ne peut pas être convertie à aucun d'eux, il renvoie intact. Le code pourrait bien sûr être ajusté pour faire seulement ce que vous voulez:

   >>> 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')
   '12'
   >>> parseStr('12.2.2')
   '12.2.2'
17
répondu krzym 2015-03-21 08:32:25

float("545.2222") et int(float("545.2222"))

15
répondu codelogic 2008-12-19 01:54:11

L'analyseur YAML peut vous aider à déterminer le type de données de votre chaîne. Utilisez yaml.load() , puis vous pouvez utiliser type(result) pour tester le type:

>>> 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
répondu 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
répondu Totoro 2017-05-30 11:39:49

j'utilise cette fonction pour que

import ast

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

il convertira la chaîne en son type

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

vous devez tenir compte de l'arrondissement pour le faire correctement.

i. e. int (5.1) => 5 int(5.6) => 5 -- mal, devrait être de 6, de sorte que nous ne nous int(5.6 + 0.5) => 6

def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)
7
répondu 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
répondu Jerry T 2015-10-09 18:04:52

C'est une version corrigée de https://stackoverflow.com/a/33017514/5973334

cela va essayer d'analyser une chaîne de caractères et de retourner soit int ou float selon ce que la chaîne représente. Il pourrait augmenter les exceptions d'analyse ou ont un certain comportement inattendu .

  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
répondu Kuzeko 2017-05-23 11:55:19

je suis surpris que personne n'ait mentionné regex parce que parfois la corde doit être préparée et normalisée avant le moulage au numéro

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

utilisation:

parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0

et au fait, quelque chose pour vérifier que vous avez un numéro:

import numbers
def is_number(value):
    return isinstance(value, numbers.Number)
    # will work with int, float, long, Decimal
3
répondu Sławomir Lenart 2017-07-12 17:01:41

Python ont cette grande flexibilité de parsing en une seule couche.

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

pour typecast en python utilisez les fonctions du constructeur du type, en passant la chaîne (ou n'importe quelle valeur que vous essayez de lancer) comme paramètre.

par exemple:

>>>float("23.333")
   23.333

dans les coulisses, python appelle les objets la méthode __float__ , qui devrait retourner une représentation float du paramètre. Ceci est particulièrement puissant, car vous pouvez définir vos propres types (en utilisant des classes) avec une méthode __float__ de sorte qu'il peut être intégré dans un flotteur à l'aide du flotteur(monobjet).

2
répondu qwerty12345 2018-07-01 20:42:31

utiliser:

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

C'est le moyen le plus pythonique que j'ai pu trouver.

1
répondu SeasonalShot 2017-01-14 15:05:50

utiliser:

>>> 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
répondu ateymuri 2017-01-14 15:06:15

voici une autre interprétation de votre question (indice: c'est vague). Il est possible que vous cherchiez quelque chose comme ceci:

def parseIntOrFloat( aString ):
    return eval( aString )

ça marche comme ça...

>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545

théoriquement, il y a une vulnérabilité d'injection. La chaîne pourrait, par exemple, être "import os; os.abort()" . Sans aucun arrière-plan sur l'origine de la chaîne, cependant, la possibilité est la spéculation théorique. Puisque la question Est vague, ce n'est pas du tout clair si cette vulnérabilité existe ou non.

-13
répondu S.Lott 2015-03-21 08:30:04