Domanda

In Python, come posso analizzare una stringa numerica come "545.2222" al valore float corrispondente, 545.2222?Oppure analizzare la stringa "31" a un numero intero, 31?

Voglio solo sapere come analizzare a galleggiante str ad a float, e (separatamente) an int str ad int.

È stato utile?

Soluzione

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

Altri suggerimenti

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

metodo di Python per controllare se una stringa è un float:

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

Un nome più lungo e più accurato per questa funzione potrebbe essere: is_convertible_to_float(value)

Qual è, e non è un galleggiante in Python potrebbe sorprendervi:

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

Pensi di sapere che cosa i numeri sono? Tu non sei così buono come si pensa! Non grande sorpresa.

Non utilizzare questo codice sul software critico vita!

Facendo ampie eccezioni in questo modo, uccidendo canarini e inghiottendo l'eccezione crea una piccola possibilità che un galleggiante valida come stringa restituirà falso. La linea di codice può float(...) fallito per uno dei mille motivi che non hanno nulla a che fare con il contenuto della stringa. Ma se si sta scrivendo software critico di vita in una lingua prototipo di anatra digitando come Python, allora hai problemi molto più grandi.

Questo è un altro metodo che merita di essere menzionato qui, ast.literal_eval :

  

Questo può essere usato per valutare in modo sicuro stringhe contenenti Python espressioni provenienti da fonti non attendibili senza la necessità di analizzare i valori stessi.

Cioè, una cassetta di sicurezza 'eval'

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
float(x) if '.' in x else int(x)

Localizzazione e virgole

Si dovrebbe considerare la possibilità di virgole nella rappresentazione stringa di un numero, per casi come float("545,545.2222") che genera un'eccezione. Invece, utilizzare metodi in locale per convertire le stringhe in numeri e interpretare correttamente le virgole. Il metodo locale.atof converte un galleggiante in un passo dopo il locale è stato impostato per la convenzione numero desiderato.

Esempio 1 - Stati Uniti convenzioni numeriche

Negli Stati Uniti e nel Regno Unito, le virgole può essere utilizzato come un separatore delle migliaia. In questo esempio con locale americano, la virgola è gestita correttamente come separatore:

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

Esempio 2 - European convenzioni numeriche

maggior parte dei paesi del mondo , le virgole sono utilizzati per i marchi decimali invece di periodi. In questo esempio con il locale Francese, la virgola è correttamente gestita come un segno di decimali:

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

Il metodo locale.atoi è anche disponibile, ma l'argomento deve essere un numero intero.

Se non siete contrari a moduli di terze parti, potreste controllare il fastnumbers modulo. Esso fornisce una funzione chiamata fast_real che fa esattamente ciò che questa domanda è chiedere e lo fa più velocemente di un'implementazione pura-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

Gli utenti codelogic e harley sono corretti, ma tenere a mente se si conosce la stringa è un numero intero (ad esempio, 545) è possibile chiamare int ( "545" ) senza prima colata a galleggiare.

Se le stringhe sono in una lista, è possibile utilizzare la funzione di carta pure.

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

E 'solo un bene se sono tutti dello stesso tipo.

La domanda sembra un po 'vecchio. Ma mi permetta di suggerire una funzione, parsestr, che fa qualcosa di simile, cioè, torna numero intero o float e se una determinata stringa di caratteri ASCII non può essere convertito in nessuna di esse si restituisce intatta. Il codice del corso potrebbe essere regolato per fare solo ciò che si vuole:

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

In Python, come posso analizzare una stringa numerica come "545.2222" nel suo valore float corrispondente, 542.2222?Oppure analizzare la stringa "31" in un numero intero, 31?Voglio solo sapere come analizzare una stringa float in un float e (separatamente) una stringa int in un int.

È positivo che tu chieda di farli separatamente.Se li mescoli, potresti crearti problemi in seguito.La risposta semplice è:

"545.2222" galleggiare:

>>> float("545.2222")
545.2222

"31" ad un numero intero:

>>> int("31")
31

Altre conversioni, int da e verso stringhe e valori letterali:

Conversioni da varie basi e dovresti conoscere la base in anticipo (10 è l'impostazione predefinita).Nota che puoi prefissarli con ciò che Python si aspetta per i suoi valori letterali (vedi sotto) o rimuovere il prefisso:

>>> 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 non conosci la base in anticipo, ma sai che avranno il prefisso corretto, Python può dedurlo per te se lo passi 0 come base:

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

Non decimale (es.Intero) Letterali da altre basi

Se la tua motivazione è che il tuo codice rappresenti chiaramente valori specifici codificati, tuttavia, potresti non aver bisogno di convertire dalle basi: puoi lasciare che Python lo faccia automaticamente con la sintassi corretta.

È possibile utilizzare i prefissi apropos per ottenere la conversione automatica in numeri interi i seguenti letterali.Questi sono validi per Python 2 e 3:

Binario, prefisso 0b

>>> 0b11111
31

Ottale, prefisso 0o

>>> 0o37
31

Esadecimale, prefisso 0x

>>> 0x1f
31

Ciò può essere utile quando si descrivono flag binari, autorizzazioni di file nel codice o valori esadecimali per i colori, ad esempio non notare le virgolette:

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

Rendere gli ottali ambigui di Python 2 compatibili con Python 3

Se vedi un numero intero che inizia con uno 0, in Python 2, questa è la sintassi ottale (deprecata).

>>> 037
31

È negativo perché sembra che il valore dovrebbe essere 37.Quindi in Python 3 ora solleva a SyntaxError:

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

Converti i tuoi ottali Python 2 in ottali che funzionano sia in 2 che in 3 con 0o prefisso:

>>> 0o37
31

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

Il YAML parser può aiutare a capire che cosa tipo di dati la stringa è. Utilizzare yaml.load(), e quindi è possibile utilizzare type(result) per verificare il 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'>

Io uso questa funzione per quel

import ast

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

Si converte la stringa al suo tipo

value = parse_str('1')  # Returns Integer
value = parse_str('1.5')  # Returns Float
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
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')

È necessario prendere in considerazione l'arrotondamento a farlo correttamente.

vale a dire. int (5.1) => 5      int (5.6) => 5 - sbagliato, dovrebbe essere 6 in modo che facciamo int (5.6 + 0.5) => 6

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

Sono sorpreso nessuno ha menzionato regex perché a volte stringa deve essere preparato e normalizzata prima del getto al numero di

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

utilizzo:

parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0

e tra l'altro, qualcosa per verificare di avere un numero:

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

Per typecast in Python utilizzare i funtions costruttore del tipo, passando la stringa (o qualsiasi valore che si sta cercando di lanciare) come parametro.

Ad esempio:

>>>float("23.333")
   23.333

Dietro le quinte, pitone sta chiamando gli oggetti __float__ metodo, che dovrebbe tornare una rappresentazione galleggiante del parametro. Questo è particolarmente potente, come si può definire tipi (utilizzando le classi) con un metodo __float__ in modo che possa essere colato in un galleggiante con galleggiante (myObject).

Questa è una versione corretta Dihttps://stackoverflow.com/a/33017514/5973334

Questo proverà ad analizzare una stringa e restituirà uno dei due int O float a seconda di cosa rappresenta la stringa.Potrebbe aumentare l'analisi delle eccezioni o avere qualche comportamento inaspettato.

  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

Usa:

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

Questo è il modo più Pythonic ho potuto trovare.

Usa:

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

Questa è una funzione che permette di convertire qualsiasi object (non solo str) per int o float, sulla base se la stringa effettiva dotazione si presenta come int o float. Inoltre se si tratta di un oggetto che ha entrambi i metodi __float e __int__, il valore di default di utilizzare __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

Ecco un'altra interpretazione della tua domanda (suggerimento: è vaga). E 'possibile che tu stai cercando qualcosa di simile a questo:

def parseIntOrFloat( aString ):
    return eval( aString )

Ecco come funziona ...

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

In teoria, c'è una vulnerabilità di iniezione. La stringa potrebbe ad esempio essere "import os; os.abort()". Senza alcun fondo su cui la stringa viene, tuttavia, la possibilità è la speculazione teorica. Dal momento che la domanda è vaga, non è affatto chiaro se questa vulnerabilità esiste realmente oppure no.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top