¿Cómo convertir cadenas en enteros en Python?

438

Tengo una tupla de tuplas de una consulta MySQL como esta:

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

Me gustaría convertir todos los elementos de cadena en enteros y volver a colocarlos en una lista de listas:

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

Traté de lograrlo evalpero aún no obtuve ningún resultado decente.

elfuego1
fuente
2
¿Quizás considere un módulo adaptador de base de datos diferente? Sé que los módulos adaptadores PostgreSQL devolverán resultados como su conjunto T2.
kquinn
3
Posible duplicado de Parse String to Float o Int
Nathan
tenga en cuenta: cuando use el mapa, obtendrá una lista de objetos de mapa en python 3 y 3.5. Esto lo hace para Python 3.5 como se mencionó anteriormente. new_list = list (list (int (a) para a en b) para b en T1 si a.isdigit ())
Invitado
Pregunta similar para una lista no anidada: Convierta todas las cadenas de una lista a int
Aran-Fey

Respuestas:

630

int()es la función incorporada estándar de Python para convertir una cadena en un valor entero. Lo llama con una cadena que contiene un número como argumento, y devuelve el número convertido a un entero:

print (int("1") + 1)

Las impresiones de arriba 2.

Si conoce la estructura de su lista, T1 (que simplemente contiene listas, solo un nivel), puede hacer esto en Python 2:

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

En Python 3:

T2 = [list(map(int, x)) for x in T1]
relajarse
fuente
44
¿por qué no T2 = map(lambda lol: map(int, lol), T1)? O mapean o enumeran las comprensiones, ambos son tontos;)
ovejas voladoras
44
@flyingsheep El mapa doble me parece una tontería, esto parece estar bien.
jamylak
¿Qué tal eliminar el ejemplo de Python 2 (debido al final de la vida útil de Python2)?
Alisso
28

Puede hacer esto con una lista de comprensión:

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

La comprensión de la lista interna ( [int(column) for column in row]) construye una listde ints a partir de una secuencia de intobjetos habilitables, como cadenas decimales, en row. La comprensión de la lista externa ( [... for row in T1])) crea una lista de los resultados de la comprensión de la lista interna aplicada a cada elemento en T1.

El fragmento de código fallará si alguna de las filas contiene objetos que no se pueden convertir int. Necesitará una función más inteligente si desea procesar filas que contengan cadenas no decimales.

Si conoce la estructura de las filas, puede reemplazar la comprensión de la lista interna con una llamada a una función de la fila. P.ej.

T2 = [parse_a_row_of_T1(row) for row in T1]
Will Harris
fuente
16

Prefiero usar solo listas de comprensión:

[[int(y) for y in x] for x in T1]
Odwl
fuente
12

En lugar de poner int( ), pon lo float( )que te permitirá usar decimales junto con enteros.

weir99
fuente
2
¿Puedes explicar más detalles sobre tu respuesta?
Rico
10

Estoy de acuerdo con las respuestas de todos hasta ahora, pero el problema es que si no tienes todos los números enteros, se estrellarán.

Si desea excluir no enteros, entonces

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

Esto produce solo dígitos reales. La razón por la que no uso la comprensión directa de la lista es porque la comprensión de la lista pierde sus variables internas.

Christian Witts
fuente
2
isdigites complicado, pruébalo -1. int(<str>)es la forma de verificar por 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
P.Hunter
fuente
77
¡Bienvenido a Stack Overflow! En lugar de solo publicar un bloque de código, explique por qué este código resuelve el problema planteado. Sin una explicación, esto no es una respuesta.
Artemix
7

Prueba esto.

x = "1"

x es una cadena porque tiene comillas alrededor, pero tiene un número.

x = int(x)

Como x tiene el número 1, puedo convertirlo en un número entero.

Para ver si una cadena es un número, puede hacer esto.

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)

Debe imprimir en IDLE True porque x es un número.

y_test = is_number(y)

print(y_test)

Debe imprimirse en IDLE False porque y no es un número.

TheRedstoneLemon
fuente
2
Su función is_number está mal. '1' no es igual a 1. Esto no es Perl. :-P
Veky
3
No reinventes la rueda, úsala x.isnumeric().
bfontaine
4

Usando listas de comprensión:

t2 = [map(int, list(l)) for l in t1]
Jon
fuente
1
en python 3 esto devuelve una lista de objetos del mapa :(
CpILL
3

En Python 3.5.1 cosas como estas funcionan:

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

y

Enter number:  4.7
4
5

Jorge.

George Moraitis
fuente
3

Ver esta función

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

Entonces

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

También puedes consultar

if val == None:  # True if input value can not be converted
    pass  # Note: Don't use 'if not val:'
Shameem
fuente
evales malvado: deberías reemplazarlo por ast.literal_eval.
Eli Korvigo el
3

Otra solución funcional más para Python 2:

from functools import partial

map(partial(map, int), T1)

Sin embargo, Python 3 será un poco desordenado:

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

podemos arreglar esto con una envoltura

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

oldmap(partial(oldmap, int), T1)
Eli Korvigo
fuente
1

Si es solo una tupla de tuplas, algo así rows=[map(int, row) for row in rows]hará el truco. (Hay una lista de comprensión y una llamada al mapa (f, lst), que es igual a [f (a) para a in lst], allí).

Eval no es lo que quieres hacer, en caso de que haya algo parecido __import__("os").unlink("importantsystemfile")en tu base de datos por alguna razón. Siempre valide su entrada (si no tiene nada más, la excepción int () aumentará si tiene una entrada incorrecta).

AKX
fuente
-1

Puedes hacer algo como esto:

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)  
Amit Rawat
fuente
-1

Quiero compartir una opción disponible que parece no mencionarse aquí todavía:

rumpy.random.permutation(x)

Generará una permutación aleatoria de la matriz x. No es exactamente lo que solicitó, pero es una solución potencial para preguntas similares.

samvoit4
fuente