Pregunta

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 con eval pero todavía no obtuve ningún resultado decente.

¿Fue útil?

Solución

int () es el 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)

Lo anterior imprime 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]

Otros consejos

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 (columna) para columna en fila] ) crea una list de int s a partir de una secuencia de Objetos compatibles con int , como cadenas decimales, en row . La comprensión de la lista externa ( [... para la fila en 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 int no puede convertir. Necesitará una función más inteligente si desea procesar filas que contienen 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. Ej.

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

Prefiero usar solo listas de comprensión:

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

En lugar de poner int () , ponga float () que le permitirá usar decimales junto con enteros.

Estoy de acuerdo con las respuestas de todos hasta ahora, pero el problema es que si no tienes todos los enteros, se bloqueará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.

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

Prueba esto.

x = "1"

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

x = int(x)

Dado que x tiene el número 1, puedo convertirlo en un 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)

Debería imprimirse en IDLE True porque x es un número.

y_test = is_number(y)

print(y_test)

Debería imprimirse en IDLE False porque y no en un número.

Uso de comprensiones de listas:

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

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

George.

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

Otra solución funcional para Python 2:

from functools import partial

map(partial(map, int), T1)

Python 3 será un poco desordenado:

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

podemos arreglar esto con un contenedor

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

oldmap(partial(oldmap, int), T1)

Si es solo una tupla de tuplas, algo así como rows = [map (int, row) para fila en filas] 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 es no lo que quiere hacer, en caso de que haya algo como __import __ (" os "). unlink (" importantsystemfile ") en su base de datos para alguna razón. Valide siempre su entrada (si no tiene nada más, la excepción int () aumentará si tiene una entrada incorrecta).

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 posible solución a preguntas similares.

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)  
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top