2013-01-31 11 views
5

Ho una lista di stringhe in forma comein Python come convertire il numero di galleggiare in una lista mista

a = ['str','5','','4.1'] 

voglio convertire tutti i numeri nella lista a stare a galla, ma lascio il resto invariato, Ti piace questa

a = ['str',5,'',4.1] 

ho provato

map(float,a) 

ma a quanto pare mi ha dato un errore perché alcuni ca stringa nnon essere convertito in float. Ho anche provato

a[:] = [float(x) for x in a if x.isdigit()] 

ma mi dà solo

[5] 

in modo che il numero di galleggiante e tutte le altre stringhe sono persi. Cosa devo fare per mantenere la stringa e il numero allo stesso tempo?

+0

Mi dispiace non essere stato molto chiaro, la lista può essere lunga e non conosco l'ordine esatto degli elementi, il che significa che non so quale sia il numero in anticipo. – LWZ

+0

Hai provato a fare ''4.1'.isdigit()', o leggendo [i documenti] (http://docs.python.org/2/library/stdtypes.html#str.isdigit)? "Restituisce true se tutti i caratteri nella stringa sono cifre ..." Poiché ''.'' non è una cifra, restituisce false. – abarnert

+0

@abarnert, hai ragione. Ho sbagliato su 4.1 ed è ora risolto. – LWZ

risposta

4
for i, x in enumerate(a): 
    try: 
     a[i] = float(x) 
    except ValueError: 
     pass 

Questo presuppone che si desidera modificare a sul posto, per la creazione di un nuovo elenco è possibile utilizzare il seguente:

new_a = [] 
for x in a: 
    try: 
     new_a.append(float(x)) 
    except ValueError: 
     new_a.append(x) 

Questo try/except approccio è standard EAFP e sarà più efficiente e meno errore incline rispetto al controllo per vedere se ogni stringa è un float valido.

+1

L'esempio one-liner fallirà in '4.1' poiché il carattere punto non è una cifra. Sostituire 'if i.isdigit()' con 'if i.replace ('.', ''). Isdigit()' dovrebbe aggirare il problema. – Valdogg21

+0

Sì, mi sono appena reso conto che ho appena rimosso l'unica fodera in quanto avresti anche avuto problemi con numeri negativi e notazione scientifica. Più facile fare il tentativo/eccetto. –

7
>>> a = ['str','5','','4.1'] 
>>> a2 = [] 
>>> for s in a: 
...  try: 
...   a2.append(float(s)) 
...  except ValueError: 
...   a2.append(s) 
>>> a2 
['str', 5.0, '', 4.0999999999999996] 

Se stai facendo la matematica decimale, si consiglia di guardare il modulo di decimali:

>>> import decimal 
>>> for s in a: 
...  try: 
...   a2.append(decimal.Decimal(s)) 
...  except decimal.InvalidOperation: 
...   a2.append(s) 
>>> a2 
['str', Decimal('5'), '', Decimal('4.1')] 
+0

Grazie.Ma perché ottengo 4.0999999999999996? Mi piacerebbe avere la stessa cifra significativa del numero originale. – LWZ

+2

@LWZ - questo è il modo in cui funzionano i numeri in virgola mobile. Vedi [questa domanda] (http://stackoverflow.com/questions/5997027/python-rounding-error-with-float-numbers). – Blair

+2

@LWZ: Perché non puoi rappresentare '4.1' esattamente come' float'. Ci sono circa 69105.00000000000001 domande su SO su questo, quindi cerca se hai bisogno di maggiori informazioni. – abarnert

5

Ecco un modo per farlo senza movimentazione eccezione e con un po 'di regex: -

>>> a = ['str','5','','4.1'] 
>>> import re 
>>> [float(x) if re.match("[+-]?(?:\d+(?:\.\d+)?|\.\d+)$", x) else x for x in a] 
4: ['str', 5.0, '', 4.1] 

si noti che, questa regex riguarderà solo una gamma base di numeri, applicabile nel tuo caso. Per più elaborata regex per abbinare una gamma più ampia di numeri in virgola mobile, come, tra cui esponenti, si può dare un'occhiata a questa domanda: -

+0

Vale la pena di ancorare con '' $ '' nel '' re'' '' '\" + (\. \ D +)? $ "' 'Per i casi patologici di '3.14pi' ecc. Migliore risposta comunque . – sotapme

+0

@sotapme. Oh sì, hai ragione. Lo modificherà. Grazie :) –

+1

La tua soluzione manca numeri negativi, non è vero? Tutto sommato, non è quasi mai una buona idea usare le espressioni regolari a meno che non siano realmente necessarie. – Vladimir

3

La mia versione:

def convert(value): 
    try: 
     return float(value) 
    except ValueError: 
     return value 

map(convert, a) 
Problemi correlati