Come convertire stringhe in numeri interi in Python?


438

Ho una tupla di tuple da una query MySQL come questa:

T1 = (('13', '17', '18', '21', '32'),
      ('07', '11', '13', '14', '28'),
      ('01', '05', '06', '08', '15', '16'))

Vorrei convertire tutti gli elementi stringa in numeri interi e rimetterli in un elenco di elenchi:

T2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

Ho provato a raggiungerlo con evalma non ho ancora ottenuto risultati decenti.


2
Forse prendere in considerazione un modulo adattatore di database diverso? So che i moduli adattatore PostgreSQL restituiranno risultati come il tuo set T2.
kquinn,

3
Possibile duplicato di Parse String su Float o Int
Nathan,

si prega di notare: quando si utilizza map, verrà visualizzato un elenco di oggetti map in Python 3 e 3.5. Questo lo fa per Python 3.5 come menzionato sopra. new_list = list (list (int (a) per a in b) per b in T1 se a.isdigit ())
Ospite

Domanda simile per un elenco non nidificato: converti tutte le stringhe in un elenco in int
Aran-Fey

Risposte:


630

int()è la funzione integrata standard di Python per convertire una stringa in un valore intero. Lo chiami con una stringa che contiene un numero come argomento e restituisce il numero convertito in un numero intero:

print (int("1") + 1)

Le stampe sopra 2.

Se conosci la struttura del tuo elenco, T1 (che contiene semplicemente elenchi, solo un livello), puoi farlo in Python 2:

T2 = [map(int, x) for x in T1]

In Python 3:

T2 = [list(map(int, x)) for x in T1]

4
perchè no T2 = map(lambda lol: map(int, lol), T1)? O la comprensione della mappa o della lista, entrambe sono sciocche;)
volare pecore il

4
@flyingsheep La doppia mappa mi sembra sciocca, questo sembra perfetto.
jamylak,

Che ne dici di rimuovere l'esempio di Python 2 (a causa della fine della vita per Python2)?
Alisso,

28

Puoi farlo con una comprensione dell'elenco:

T2 = [[int(column) for column in row] for row in T1]

La comprensione della lista interna ( [int(column) for column in row]) costruisce a listof ints da una sequenza di intoggetti -able, come stringhe decimali, in row. La comprensione dell'elenco esterno ( [... for row in T1])) crea un elenco dei risultati della comprensione dell'elenco interno applicato a ciascun elemento in T1.

Lo snippet di codice avrà esito negativo se una delle righe contiene oggetti per i quali non è possibile convertire int. Avrai bisogno di una funzione più intelligente se desideri elaborare righe contenenti stringhe non decimali.

Se si conosce la struttura delle righe, è possibile sostituire la comprensione dell'elenco interno con una chiamata a una funzione della riga. Per esempio.

T2 = [parse_a_row_of_T1(row) for row in T1]

16

Preferirei usare solo elenchi di comprensione:

[[int(y) for y in x] for x in T1]

12

Invece di mettere int( ), metti float( )che ti permetterà di usare i decimali insieme ai numeri interi.


2
Puoi spiegare maggiori dettagli sulla tua risposta?
Rico,

10

Sono d'accordo con le risposte di tutti finora, ma il problema è che se non si hanno tutti i numeri interi si bloccheranno.

Se si desidera escludere numeri non interi, allora

T1 = (('13', '17', '18', '21', '32'),
      ('07', '11', '13', '14', '28'),
      ('01', '05', '06', '08', '15', '16'))
new_list = list(list(int(a) for a in b) for b in T1 if a.isdigit())

Questo produce solo cifre effettive. Il motivo per cui non utilizzo la comprensione diretta dell'elenco è perché la comprensione dell'elenco perde le loro variabili interne.


2
isdigitè difficile, provalo -1. int(<str>)è il modo di controllare da try/ except.
totoro,

9
T3=[]

for i in range(0,len(T1)):
    T3.append([])
    for j in range(0,len(T1[i])):
        b=int(T1[i][j])
        T3[i].append(b)

print T3

7
Benvenuto in Stack Overflow! Anziché pubblicare solo un blocco di codice, spiega perché questo codice risolve il problema posto. Senza una spiegazione, questa non è una risposta.
Artemix,

7

Prova questo.

x = "1"

x è una stringa perché contiene delle virgolette, ma contiene un numero.

x = int(x)

Poiché x contiene il numero 1, posso trasformarlo in un numero intero.

Per vedere se una stringa è un numero, puoi farlo.

def is_number(var):
    try:
        if var == int(var):
            return True
    except Exception:
        return False

x = "1"

y = "test"

x_test = is_number(x)

print(x_test)

Dovrebbe stampare su IDLE True perché x è un numero.

y_test = is_number(y)

print(y_test)

Dovrebbe stampare su IDLE False perché y non è un numero.


2
La tua funzione is_number è errata. '1' non è uguale a 1. Questo non è Perl. :-P
Veky,

3
Non reinventare la ruota, usare x.isnumeric().
bfontaine,

4

Utilizzando la comprensione dell'elenco:

t2 = [map(int, list(l)) for l in t1]

1
in Python 3 restituisce un elenco di oggetti mappa :(
CpILL

3

In Python 3.5.1 cose come queste funzionano:

c = input('Enter number:')
print (int(float(c)))
print (round(float(c)))

e

Enter number:  4.7
4
5

Giorgio.


3

Vedi questa funzione

def parse_int(s):
    try:
        res = int(eval(str(s)))
        if type(res) == int:
            return res
    except:
        return

Poi

val = parse_int('10')  # Return 10
val = parse_int('0')  # Return 0
val = parse_int('10.5')  # Return 10
val = parse_int('0.0')  # Return 0
val = parse_int('Ten')  # Return None

Puoi anche controllare

if val == None:  # True if input value can not be converted
    pass  # Note: Don't use 'if not val:'

evalè male: dovresti sostituirlo con ast.literal_eval.
Eli Korvigo,

3

Ancora un'altra soluzione funzionale per Python 2:

from functools import partial

map(partial(map, int), T1)

Python 3 sarà un po 'confuso però:

list(map(list, map(partial(map, int), T1)))

possiamo sistemarlo con un wrapper

def oldmap(f, iterable):
    return list(map(f, iterable))

oldmap(partial(oldmap, int), T1)

1

Se è solo una tupla di tuple, qualcosa del genere rows=[map(int, row) for row in rows]farà il trucco. (C'è una comprensione della lista e una chiamata alla mappa (f, lst), che è uguale a [f (a) per a in lst], lì dentro.)

Eval non è quello che vuoi fare, nel caso ci sia qualcosa di simile __import__("os").unlink("importantsystemfile")nel tuo database per qualche motivo. Convalida sempre il tuo input (se non altro, l'eccezione int () aumenterà se hai un input errato).


-1

Puoi fare qualcosa del genere:

T1 = (('13', '17', '18', '21', '32'),  
     ('07', '11', '13', '14', '28'),  
     ('01', '05', '06', '08', '15', '16'))  
new_list = list(list(int(a) for a in b if a.isdigit()) for b in T1)  
print(new_list)  

-1

Voglio condividere un'opzione disponibile che non sembra essere ancora menzionata qui:

rumpy.random.permutation(x)

Genererà una permutazione casuale dell'array x. Non esattamente quello che hai chiesto, ma è una potenziale soluzione a domande simili.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.