Comment analyser une chaîne en un flottant ou un int?


2253

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

Je veux juste savoir comment analyser un flotteur str en un floatet (séparément) un int str en un int.


7
En règle générale, si vous avez un objet en Python et que vous souhaitez le convertir en ce type d'objet, faites appel type(my_object)à lui. Le résultat peut généralement être appelé en tant que fonction pour effectuer la conversion. Par exemple, les type(100)résultats en int, vous pouvez donc appeler int(my_object)pour essayer de convertir my_objecten un entier. Cela ne fonctionne pas toujours, mais c'est une bonne "première estimation" lors du codage.
robertlayton

1
int(x) if int(x) == float(x) else float(x)
tcpaiva

Réponses:


2628
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545

8
je me demande juste pourquoi il y a '04' à la fin? pourquoi pas simplement '00'? aussi ma version actuelle de python n'a pas '04'.
Mangat Rai Modi

54
@MangatRaiModi Les nombres à virgule flottante sont intrinsèquement imparfaits pour représenter les décimales. Pour plus d'informations, voir stackoverflow.com/q/21895756/931277
dokkaebi

19
pourquoi pas simplement int(a)mais int(float(a))?
idclev 463035818

24
int(a)donnera une erreur indiquant que la chaîne n'est pas un entier valide:, ValueError: invalid literal for int() with base 10: '545.222'mais la conversion d'un flottant en un int est une conversion prise en charge.
David Parks

4
Vous devez gérer ValueErrorsi vous voulez être en sécurité
Joe Bobson

515
def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)

81
le mélange implicite de flotteurs / entiers peut conduire à des bogues subtils en raison d'une possible perte de précision lors du travail avec des flotteurs ou à des résultats différents pour l' /opérateur sur les flotteurs / pouces. Selon le contexte, il peut être préférable de renvoyer int ou float, pas les deux.
jfs

14
@JFSebastian Vous avez tout à fait raison, mais il y a des moments où vous voulez que l'entrée dicte celle-là. Laisser l'entrée dicter laquelle peut fonctionner correctement avec la frappe de canard.
TimothyAWiseman

4
Vous pouvez en imbriquer une autre trypour lever une exception lorsqu'elle n'est pas convertible en flottant.
iBug

2
Échoue avecs = u'\u0000'
Matt Hancock

1
@iBug Bonne idée! Je recommande d' ValueErrorexcept
ajouter

511

Méthode Python pour vérifier si une chaîne est un flottant:

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 en Python peut 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 quels sont les chiffres? Vous n'êtes pas aussi bon que vous le pensez! Pas une grosse surprise.

N'utilisez pas ce code sur des logiciels vitaux!

Attraper de larges exceptions de cette façon, tuer les canaris et engloutir l'exception crée une toute petite chance qu'un flottant valide en tant que chaîne retourne faux. La float(...)ligne de code peut échouer pour mille raisons qui n'ont rien à voir avec le contenu de la chaîne. Mais si vous écrivez des logiciels vitaux dans un langage prototype de type canard comme Python, vous avez des problèmes beaucoup plus importants.


1
Si vrai devient 1, c'est que j'ai hérité du C ++ je pense
FindOutIslamNow

6
J'ai posté cette réponse en 2014. Ce UTF-8glyphe pour un chinois 4s'est transformé au fil des ans en fonction de la façon dont les développeurs stackoverflow modifient leur schéma de codage de caractères sur leur pile d'outils Microsoft. C'est une curiosité de le voir basculer au fil des ans alors que de nouveaux schémas de conversion affirment leurs nouvelles idéologies. Mais oui, tout UTF-8glyphe pour un numérique oriental oriental n'est pas un flotteur en Python. Bazinga.
Eric Leschinski

4
comment cela peut-il être si positivement voté, avec une si large exception?
E.Serra

Tout avec des espaces entre les deux ne peut pas être converti, comme "- 12.3"et"45 e6"
Simon

1
Cette clause d'exception devrait être limitée àTypeError, ValueError
wim

131

C'est une autre méthode qui mérite d'être mentionnée ici, ast.literal_eval :

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

Autrement dit, un «eval» sûr

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31

11
ce n'est pas une bonne solution au problème. Cela fonctionne bien dans Python 2, mais ce qui suit se produit dans Python 3: python >>> import ast >>> ast.literal_eval('1-800-555-1212') -2566 >>> Pour clarifier pourquoi c'est un problème, si vous voulez laisser les numéros de téléphone seuls et ne pas supposer que ce sont des expressions mathématiques, cette approche n'est pas pour vous.
royce3

6
@ royce3 Oui, c'est un bon point et les utilisateurs doivent se méfier. Le comportement a été modifié à l'origine afin de résoudre certains problèmes liés à l'analyse de littéraux complexes. C'est sans doute un bug ast.literal_evalet a été discuté ici .
wim

79
float(x) if '.' in x else int(x)

21
Remarque: soyez prudent lorsque vous traitez le montant d'argent passé sous forme de chaînes, car certains pays utilisent "," comme séparateurs décimaux
Ben G

127
@Emile: Je n'appellerais pas "2e-3" un "cas extrême". Cette réponse est juste cassée.
jchl

14
@BenG NE manipulez PAS l'argent comme un flottant. C'est demander des ennuis. Utilisez décimal pour de l'argent! (Mais votre commentaire sur ',' est toujours valable et important)
ToolmakerSteve

4
N'oubliez pas que "pas un nombre" (NaN) et +/- infini sont également des valeurs flottantes valides. Il en float("nan")est de même pour une valeur flottante parfaitement valide que la réponse ci-dessus n'attraperait pas du tout
Ronny Andersson

2
Facilement cassable par une adresse IP - 192.168.0.1; ou"This is not a good approach. :)"
Todor Minakov

69

Localisation et virgules

Vous devriez considérer la possibilité de virgules dans la représentation sous forme de chaîne d'un nombre, pour les cas comme celui float("545,545.2222")qui lève une exception. À la place, utilisez des méthodes dans localepour convertir les chaînes en nombres et interpréter correctement les virgules. La locale.atofméthode se transforme en un flottant en une seule étape une fois que les paramètres régionaux ont été définis pour la convention de nombre souhaitée.

Exemple 1 - Conventions de numérotation aux États-Unis

Aux États-Unis et au Royaume-Uni, les virgules peuvent être utilisées comme séparateur de milliers. Dans cet exemple avec les paramètres régionaux américains, la virgule est gérée correctement comme 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 de numérotation européennes

Dans la majorité des pays du monde , les virgules sont utilisées pour les décimales au lieu des points. Dans cet exemple avec les paramètres régionaux français, la virgule est correctement géré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.atoiest également disponible, mais l'argument doit être un entier.


Cela semble être une solution idéale lorsque vous savez si un flottant ou un int doit être retourné, mais comment pouvez-vous obtenir ceci pour renvoyer un int uniquement si un int a été passé? Par exemple, x = '1'; locale.atof(x)retourne 1.0quand je veux réellement 1.
user5359531

En utilisant la méthode de Dino, je suppose que la réponse serait d'utiliser quelque chose comme ceci:locale.atof(x) if locale.localeconv().get('decimal_point') in x else locale.atoi(x)
user5359531

Je recommanderais d'utiliser la méthode de Javier ci-dessus (encapsulation locale.atoidans un essai et utilisation locale.atofsur exception - c'est probablement plus lisible.
Mark Chackerian

27

Si vous n'êtes pas opposé aux modules tiers, vous pouvez consulter le module fastnumbers . 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

24

Les utilisateurs codelogic et harley sont corrects, mais gardez à l'esprit que si vous savez que la chaîne est un entier (par exemple, 545), vous pouvez appeler int ("545") sans lancer le premier casting pour flotter.

Si vos chaînes sont dans une liste, vous pouvez également utiliser la fonction de carte.

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


21

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" en un entier, 31? Je veux juste savoir comment analyser une chaîne flottante en flottant et (séparément) une chaîne int en un int.

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

"545.2222" flotter:

>>> float("545.2222")
545.2222

"31" à un entier:

>>> int("31")
31

Autres conversions, entiers vers et depuis les chaînes et les littéraux:

Conversions de différentes bases, et vous devez 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éraux (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 en déduire cela si vous passez 0comme base:

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

Littéraux non décimaux (c'est-à-dire entiers) d'autres bases

Si votre motivation est que votre propre code représente clairement des valeurs spécifiques codées en dur, cependant, vous n'aurez peut-être pas besoin de convertir à partir des bases - vous pouvez laisser Python le faire automatiquement pour vous avec la syntaxe correcte.

Vous pouvez utiliser les préfixes apropos pour obtenir la conversion automatique en entiers avec les littéraux suivants . 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 lors de la description des indicateurs binaires, des autorisations de fichier dans le code ou des valeurs hexadécimales pour les couleurs - par exemple, notez les 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

Rendre les octaux ambigus de Python 2 compatibles avec Python 3

Si vous voyez un entier qui commence par un 0, en Python 2, il s'agit de la syntaxe octale (obsolète).

>>> 037
31

C'est mauvais car il semble que 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 octaux qui fonctionnent à la fois en 2 et 3 avec le 0opréfixe:

>>> 0o37
31

20

La question semble un peu ancienne. Mais permettez-moi de suggérer une fonction, parseStr, qui rend quelque chose de similaire, c'est-à-dire qui renvoie un entier ou un flottant et si une chaîne ASCII donnée ne peut être convertie en aucune d'entre elles, elle la renvoie intacte. Le code peut bien sûr être ajusté pour ne faire que 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$5')
   '12$5'
   >>> parseStr('12.2.2')
   '12.2.2'

8
1e3est un nombre en python, mais une chaîne selon votre code.
Cees Timmerman

16

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


1
Cela vous donnera un objet flottant si votre chaîne se trouve être "0" ou "0.0", plutôt que l'int qu'elle donne pour d'autres nombres valides.
Brian

14

J'utilise cette fonction pour ça

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

Veuillez noter que parse_str(' 1')(avec un espace) reviendra None, non 1.
musiphil

13

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

11
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

1
Pourquoi voudriez-vous soulever dans votre exceptsection si vous ne faites rien là-bas? float () soulèverait pour vous.
Greg0ry

1
vous avez raison, je suppose que j'ai copié et collé à partir d'une fonctionnalité que je soulevais une exception particulière. va éditer. merci
Totoro

1
Cela va essayer d'analyser une chaîne et de retourner soit intou floatselon ce que la chaîne représente. Il peut augmenter les exceptions d'analyse ou [avoir un comportement inattendu] [1].
Kuzeko

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

6

Vous devez prendre en compte l'arrondi pour le faire correctement.

Ie int (5.1) => 5 int (5.6) => 5 - faux, devrait être 6 donc nous faisons int (5.6 + 0.5) => 6

def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)

4
Bon point. Cela provoque une inflation, cependant, Python 3 et d' autres langages modernes utilisent l'arrondi bancaire.
Cees Timmerman

2
Cette réponse est fausse (comme écrit à l'origine). Il embrouille les deux cas de intet float. Et cela donnera une exception, quand nest une chaîne, comme OP le souhaite. Peut - être que vous vouliez dire: Quand un intrésultat souhaité, rounddevrait être fait conversion AFTER flotter. Si la fonction doit TOUJOURS retourner un entier, alors vous n'avez pas besoin de la partie except - le corps entier de la fonction peut l'être int(round(float(input))). Si la fonction doit retourner un int si possible, sinon un flottant, alors la solution originale de javier est correcte!
ToolmakerSteve

5

Je suis surpris que personne ne mentionne l'expression régulière car parfois la chaîne doit être préparée et normalisée avant de lancer le nombre

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

usage:

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

5

Pour transtyper en python, utilisez les fonctions constructeur du type, en passant la chaîne (ou la valeur que vous essayez de caster) comme paramètre.

Par exemple:

>>>float("23.333")
   23.333

Dans les coulisses, python appelle la __float__méthode des objets , qui devrait renvoyer une représentation flottante du paramètre. Ceci est particulièrement puissant, car vous pouvez définir vos propres types (en utilisant des classes) avec une __float__méthode afin qu'il puisse être converti en un float en utilisant float (myobject).


3

Il s'agit d'une version corrigée de https://stackoverflow.com/a/33017514/5973334

Cela va essayer d'analyser une chaîne et de retourner soit intou floatselon ce que la chaîne représente. Il peut augmenter les exceptions d'analyse ou avoir un 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

2

Passez votre chaîne à cette fonction:

def string_to_number(str):
  if("." in str):
    try:
      res = float(str)
    except:
      res = str  
  elif(str.isdigit()):
    res = int(str)
  else:
    res = str
  return(res)

Il renverra int, float ou string selon ce qui a été passé.

chaîne qui est un int

print(type(string_to_number("124")))
<class 'int'>

chaîne qui est un flotteur

print(type(string_to_number("12.4")))
<class 'float'>

chaîne qui est une chaîne

print(type(string_to_number("hello")))
<class 'str'>

chaîne qui ressemble à un flotteur

print(type(string_to_number("hel.lo")))
<class 'str'>

1

Utilisation:

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 la façon la plus Pythonique que j'ai pu trouver.


Le générateur s'arrête après la première interprétation de float. Le bloc trycatchdevrait probablement être à l'intérieur de la forboucle.
musiphil

1

Gère hex, octal, binaire, décimal et flottant

Cette solution gérera toutes les conventions de chaîne pour les nombres (tout ce que je sais).

def to_number(n):
    ''' Convert any number representation to a number 
    This covers: float, decimal, hex, and octal numbers.
    '''

    try:
        return int(str(n), 0)
    except:
        try:
            # python 3 doesn't accept "010" as a valid octal.  You must use the
            # '0o' prefix
            return int('0o' + n, 0)
        except:
            return float(n)

Cette sortie de scénario de test illustre ce dont je parle.

======================== CAPTURED OUTPUT =========================
to_number(3735928559)   = 3735928559 == 3735928559
to_number("0xFEEDFACE") = 4277009102 == 4277009102
to_number("0x0")        =          0 ==          0
to_number(100)          =        100 ==        100
to_number("42")         =         42 ==         42
to_number(8)            =          8 ==          8
to_number("0o20")       =         16 ==         16
to_number("020")        =         16 ==         16
to_number(3.14)         =       3.14 ==       3.14
to_number("2.72")       =       2.72 ==       2.72
to_number("1e3")        =     1000.0 ==       1000
to_number(0.001)        =      0.001 ==      0.001
to_number("0xA")        =         10 ==         10
to_number("012")        =         10 ==         10
to_number("0o12")       =         10 ==         10
to_number("0b01010")    =         10 ==         10
to_number("10")         =         10 ==         10
to_number("10.0")       =       10.0 ==         10
to_number("1e1")        =       10.0 ==         10

Voici le test:

class test_to_number(unittest.TestCase):

    def test_hex(self):
        # All of the following should be converted to an integer
        #
        values = [

                 #          HEX
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (0xDEADBEEF  , 3735928559), # Hex
                ("0xFEEDFACE", 4277009102), # Hex
                ("0x0"       ,          0), # Hex

                 #        Decimals
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (100         ,        100), # Decimal
                ("42"        ,         42), # Decimal
            ]



        values += [
                 #        Octals
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (0o10        ,          8), # Octal
                ("0o20"      ,         16), # Octal
                ("020"       ,         16), # Octal
            ]


        values += [
                 #        Floats
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (3.14        ,       3.14), # Float
                ("2.72"      ,       2.72), # Float
                ("1e3"       ,       1000), # Float
                (1e-3        ,      0.001), # Float
            ]

        values += [
                 #        All ints
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                ("0xA"       ,         10), 
                ("012"       ,         10), 
                ("0o12"      ,         10), 
                ("0b01010"   ,         10), 
                ("10"        ,         10), 
                ("10.0"      ,         10), 
                ("1e1"       ,         10), 
            ]

        for _input, expected in values:
            value = to_number(_input)

            if isinstance(_input, str):
                cmd = 'to_number("{}")'.format(_input)
            else:
                cmd = 'to_number({})'.format(_input)

            print("{:23} = {:10} == {:10}".format(cmd, value, expected))
            self.assertEqual(value, expected)

0

Utilisation:

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

Il s'agit d'une fonction qui convertira tout object(et pas seulement str) en intou float, selon que la chaîne réelle fournie ressemble à int ou float. De plus, si c'est un objet qui a les deux méthodes __floatet __int__, il utilise par défaut__float__

def conv_to_num(x, num_type='asis'):
    '''Converts an object to a number if possible.
    num_type: int, float, 'asis'
    Defaults to floating point in case of ambiguity.
    '''
    import numbers

    is_num, is_str, is_other = [False]*3

    if isinstance(x, numbers.Number):
        is_num = True
    elif isinstance(x, str):
        is_str = True

    is_other = not any([is_num, is_str])

    if is_num:
        res = x
    elif is_str:
        is_float, is_int, is_char = [False]*3
        try:
            res = float(x)
            if '.' in x:
                is_float = True
            else:
                is_int = True
        except ValueError:
            res = x
            is_char = True

    else:
        if num_type == 'asis':
            funcs = [int, float]
        else:
            funcs = [num_type]

        for func in funcs:
            try:
                res = func(x)
                break
            except TypeError:
                continue
        else:
            res = x

-1

En utilisant les méthodes int et float, nous pouvons convertir une chaîne en entier et en flottant.

s="45.8"
print(float(s))

y='67'
print(int(y))

Cette réponse n'ajoute rien de nouveau. Voir, par exemple, cette réponse qui donne les mêmes informations et plus encore.
Georgy

-3

eval()est une très bonne solution à cette question. Il n'a pas besoin de vérifier si le nombre est entier ou flottant, il donne juste l'équivalent correspondant. Si d'autres méthodes sont requises, essayez

if '.' in string:
    print(float(string))
else:
    print(int(string))

try-except peut également être utilisé comme alternative. Essayez de convertir la chaîne en int dans le bloc try. Si la chaîne est une valeur flottante, elle générera une erreur qui sera interceptée dans le bloc except, comme ceci

try:
    print(int(string))
except:
    print(float(string))

-10

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

def parseIntOrFloat( aString ):
    return eval( aString )

Cela fonctionne comme ça ...

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

Théoriquement, il existe une vulnérabilité d'injection. La chaîne pourrait, par exemple, être "import os; os.abort()". Sans aucun contexte sur la provenance de la chaîne, cependant, la possibilité est une spéculation théorique. La question étant vague, il n'est pas du tout clair si cette vulnérabilité existe réellement ou non.


7
Même si son entrée est sûre à 100%, elle eval()est plus de 3 fois plus lente que try: int(s) except: float(s).
Cees Timmerman

1
Eh bien, evalc'est une mauvaise pratique (vous devez le savoir parce que vous avez une réputation de 310k)
U10-Forward
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.