Hoe kan ik een string ontleden naar een float of int?

Hoe kan ik in Python een numerieke tekenreeks zoals "545.2222"ontleden naar de bijbehorende float-waarde, 545.2222? Of ontleden de string "31"naar een geheel getal, 31?

Ik wil gewoon weten hoe ik een floatstrnaar een floatkan parseren, en (afzonderlijk) een intstrnaar een int.


Antwoord 1, autoriteit 100%

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

Antwoord 2, autoriteit 19%

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

Antwoord 3, autoriteit 19%

Python-methode om te controleren of een string een float is:

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

Een langere en nauwkeurigere naam voor deze functie zou kunnen zijn: is_convertible_to_float(value)

Wat wel en niet een float is in Pythonzal je misschien verbazen:

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

Denk je dat je weet wat getallen zijn? Je bent niet zo goed als je denkt! Geen grote verrassing.

Gebruik deze code niet op levenskritieke software!

Op deze manier brede uitzonderingen opvangen, kanaries doden en de uitzondering opslokken, creëert een kleine kans dat een geldige float als string false retourneert. De regel float(...)code kan om duizend redenen mislukken die niets te maken hebben met de inhoud van de tekenreeks. Maar als je levenskritieke software schrijft in een prototypetaal voor het typen van eenden, zoals Python, dan heb je veel grotere problemen.


Antwoord 4, autoriteit 5%

Dit is een andere methode die het verdient om hier genoemd te worden, ast.literal_eval:

Dit kan worden gebruikt voor het veilig evalueren van strings die Python-expressies bevatten van niet-vertrouwde bronnen zonder de waarden zelf te hoeven ontleden.

Dat wil zeggen, een veilige ‘eval’

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

Antwoord 5, autoriteit 3%

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

Antwoord 6, autoriteit 3%

Lokalisatie en komma’s

Je moet rekening houden met de mogelijkheid van komma’s in de tekenreeksrepresentatie van een getal, voor gevallen zoals float("545,545.2222")die een uitzondering genereert. Gebruik in plaats daarvan methoden in localeom de tekenreeksen naar getallen te converteren en komma’s correct te interpreteren. De methode locale.atofconverteert in één stap naar een float zodra de landinstelling is ingesteld voor de gewenste getalconventie.

Voorbeeld 1 — Amerikaanse nummerconventies

In de Verenigde Staten en het Verenigd Koninkrijk kunnen komma’s worden gebruikt als scheidingsteken voor duizendtallen. In dit voorbeeld met Amerikaanse landinstelling wordt de komma correct verwerkt als scheidingsteken:

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

Voorbeeld 2 — Europese nummerconventies

In de meerderheid van landen van de wereldworden komma’s gebruikt voor decimale tekens in plaats van punten. In dit voorbeeld met Franse landinstelling wordt de komma correct behandeld als een decimaal teken:

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

De methode locale.atoiis ook beschikbaar, maar het argument moet een geheel getal zijn.


Antwoord 7

Als je niet vies bent van modules van derden, kun je de module fastnumbersbekijken. Het biedt een functie genaamd fast_realdie precies doet wat deze vraag is vraagt om en doet het sneller dan een pure Python-implementatie:

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

Antwoord 8

Gebruikers codelogicen harleyhebben gelijk, maar onthoud dat als u weet dat de string een geheel getal is (bijvoorbeeld 545), u int(“545”) kunt aanroepen ) zonder eerst te werpen om te drijven.

Als uw strings in een lijst staan, kunt u ook de kaartfunctie gebruiken.

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

Het is alleen goed als ze allemaal van hetzelfde type zijn.


Antwoord 9

De vraag lijkt een beetje oud. Maar laat me een functie voorstellen, parseStr, die iets soortgelijks maakt, dat wil zeggen, integer of float retourneert en als een gegeven ASCII-string niet naar geen van hen kan worden geconverteerd, retourneert het deze onaangeroerd. De code kan natuurlijk worden aangepast om alleen te doen wat u wilt:

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

Antwoord 10

float("545.2222")en int(float("545.2222"))


Antwoord 11

De YAML-parser kan je helpen erachter te komen welk datatype je string is. Gebruik yaml.load(), en dan kun je type(result)gebruiken om te testen op 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'>

Antwoord 12

Daar gebruik ik deze functie voor

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

Het zal de string naar zijn type converteren

value = parse_str('1')  # Returns Integer
value = parse_str('1.5')  # Returns Float

Antwoord 13

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

Antwoord 14

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

Antwoord 15

Je moet rekening houden met afronding om dit goed te doen.

D.w.z. int(5.1) => 5
int(5.6) => 5 — fout, zou 6 moeten zijn, dus we doen int(5.6 + 0.5) => 6

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

Antwoord 16

Het verbaast me dat niemand regex noemde, omdat strings soms moeten worden voorbereid en genormaliseerd voordat ze naar nummer worden gecast

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

gebruik:

parseNumber('13,345')
> 13345.0
parseNumber('- 123 000')
> -123000.0
parseNumber('99999\n')
> 99999.0

en trouwens, iets om te verifiëren dat je een nummer hebt:

import numbers
def is_number(value):
    return isinstance(value, numbers.Number)
    # will work with int, float, long, Decimal

Antwoord 17

Geef je string door aan deze functie:

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)

Het zal int, float of string retourneren, afhankelijk van wat er is doorgegeven.

tekenreeks die een int is

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

string die een float is

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

tekenreeks die een tekenreeks is

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

string die eruitziet als een float

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

Antwoord 18

Om in python te typen, gebruikt u de constructorfuncties van het type, waarbij u de tekenreeks (of welke waarde u ook probeert te casten) als parameter door te geven.

Bijvoorbeeld:

>>>float("23.333")
   23.333

Achter de schermen roept python de methode objects __float__aan, die een float-representatie van de parameter zou moeten retourneren. Dit is vooral krachtig, omdat je je eigen typen kunt definiëren (met klassen) met een __float__-methode, zodat het in een float kan worden gegoten met float(myobject).


Antwoord 19

Behandelt hex, octaal, binair, decimaal en float

Deze oplossing verwerkt alle stringconventies voor getallen (alles wat ik weet).

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)

Deze testcase-output illustreert waar ik het over heb.

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

Hier is de 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)

20

Dit is een gecorrigeerde versie van
https://stackoverflow.com/a/33017514/5973334

Hierdoor probeert u een tekenreeks te ontleden en een intof floatte retourneren, afhankelijk van wat de reeks vertegenwoordigt.
Het zou kunnen opstaan ​​uitzonderingen of een onverwacht gedrag hebben .

 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

21

a = int(float(a)) if int(float(a)) == float(a) else float(a)

22

Gebruik:

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

Dit is de meest pythonische manier waarop ik kan bedenken.


23

Gebruik:

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

Antwoord 24

Dit is een functie die elk object(niet alleen str) naar intof floatzal converteren, gebaseerd op of de daadwerkelijk geleverde string er lijkt opintof float. Verder, als het een object is dat zowel __floatals __int__methoden heeft, gebruikt het standaard __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

Antwoord 25

voor nummer en teken samen :

string_for_int = "498 results should get"
string_for_float = "498.45645765 results should get"

eerste import re:

import re
 #for get integer part:
 print(int(re.search(r'\d+', string_for_int).group())) #498
 #for get float part:
 print(float(re.search(r'\d+\.\d+', string_for_float).group())) #498.45645765

voor eenvoudig model:

value1 = "10"
value2 = "10.2"
print(int(value1)) #10
print(float(value2)) #10.2

Antwoord 26

dit is een oude vraag en heeft al veel antwoorden gekregen.
maar als je te maken hebt met gemengde gehele getallen en floats en je wilt een consistente manier om met je gemengde gegevens om te gaan, dan is hier mijn oplossing met de juiste docstring:

def parse_num(candidate):
    """parse string to number if possible
    work equally well with negative and positive numbers, integers and floats.
    Args:
        candidate (str): string to convert
    Returns:
        float | int | None: float or int if possible otherwise None
    """
    try:
        float_value = float(candidate)
    except ValueError:
        return None
    # optional part if you prefer int to float when decimal part is 0 
    if float_value.is_integer():
        return int(float_value)
    # end of the optional part
    return float_value
# test
candidates = ['34.77', '-13', 'jh', '8990', '76_3234_54']
res_list = list(map(parse_num, candidates))
print('Before:')
print(candidates)
print('After:')
print(res_list)

uitvoer:

Before:
['34.77', '-13', 'jh', '8990', '76_3234_54']
After:
[34.77, -13, None, 8990, 76323454]

Antwoord 27

Door de methoden int en float te gebruiken, kunnen we een string converteren naar integer en floats.

s="45.8"
print(float(s))
y='67'
print(int(y))

Antwoord 28

Hier is een andere interpretatie van uw vraag (hint: het is vaag). Het is mogelijk dat u zoiets zoekt:

def parseIntOrFloat( aString ):
    return eval( aString )

Het werkt als volgt…

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

Theoretisch is er een injectiekwetsbaarheid. De tekenreeks kan bijvoorbeeld "import os; os.abort()"zijn. Zonder enige achtergrond over waar de string vandaan komt, is de mogelijkheid echter theoretische speculatie. Omdat de vraag vaag is, is het helemaal niet duidelijk of deze kwetsbaarheid daadwerkelijk bestaat of niet.

Other episodes