Obteniendo <objeto generador

Tengo 2 listas:

first_lst = [('-2.50', 0.49, 0.52), ('-2.00', 0.52, 0.50)] second_lst = [('-2.50', '1.91', '2.03'), ('-2.00', '1.83', '2.08')] 

Quiero hacer los siguientes cálculos matemáticos:

Multiplique 0.49 por 1.91 (los valores correspondientes de first_lst y second_lst ), y multiplique 0.52 por 2.03 (los valores correspondientes también). Quiero hacerlo bajo la condición de que los valores en la posición 0 en cada tupla correspondiente sean -2.50 por lo que -2.50 == -2.50 etc. Obviamente, también hacemos los mismos cálculos para volver a agrupar las tuplas.

Mi código:

 [((fir[0], float(fir[1])*float(sec[1]), float(fir[2])*float(sec[2])) for fir in first_lst) for sec in second_lst if fir[0] == sec[0]] 

Genera sin embargo algún objeto:

 [<generator object  at 0x0223E2B0>] 

¿Puedes ayudarme a arreglar el código?

tuple() usar tuple() o list() para convertir esa expresión del generador en una list o tuple :

 [tuple((fir[0], fir[1]*sec[1], fir[2]*sec[2]) for fir in first_lst)\ for sec in second_lst if fir[0] == sec[0]] 

Versión de trabajo de su código:

 >>> first_lst = [tuple(float(y) for y in x) for x in first_lst] >>> second_lst = [tuple(float(y) for y in x) for x in second_lst] >>> [((fir[0],) + tuple(x*y for x, y in zip(fir[1:], sec[1:]))) \ for fir in first_lst for sec in second_lst if fir[0]==sec[0]] [(-2.5, 0.9359, 1.0555999999999999), (-2.0, 0.9516000000000001, 1.04)] 

Teniendo en cuenta que su first_lst y second_lst se definen de la siguiente manera.

 >>> first_lst = [('-2.50', '0.49', '0.52'), ('-2.00', '0.52', '0.50')] >>> second_lst = [('-2.50', '1.91', '2.03'), ('-2.00', '1.83', '2.08')] 

La siguiente lista de comprensión puede ser útil.

 >>> [tuple((float(elem[0][0]), float(elem[0][1])*float(elem[1][1]), float(elem[0][2])*float(elem[1][2]))) for elem in zip(first_lst, second_lst) if elem[0][0]==elem[1][0]] [(-2.5, 0.9359, 1.0555999999999999), (-2.0, 0.9516000000000001, 1.04)] 

Hay 2 temas a considerar.

El código original generará el error:

 >>> first_lst = [('-2.50', 0.49, 0.52), ('-2.00', 0.52, 0.50)] >>> second_lst = [('-2.50', '1.91', '2.03'), ('-2.00', '1.83', '2.08')] >>> [((fir[0], float(fir[1])*float(sec[1]), float(fir[2])*float(sec[2])) for fir in first_lst) for sec in second_lst if fir[0] == sec[0]] Traceback (most recent call last): File "", line 1, in  File "", line 1, in  NameError: name 'fir' is not defined >>> 

y se menciona el mensaje .

1) Corrigamos el código con la cantidad mínima de cambios creando una lista de comprensión :

 >>> first_lst = [('-2.50', 0.49, 0.52), ('-2.00', 0.52, 0.50)] >>> second_lst = [('-2.50', '1.91', '2.03'), ('-2.00', '1.83', '2.08')] >>> [(fir[0],fir[1]*float(sec[1]),fir[2]*float(sec[2])) for fir in first_lst for sec in second_lst if fir[0] == sec[0]] # list comprehension [('-2.50', 0.9359, 1.0555999999999999), ('-2.00', 0.9516000000000001, 1.04)] >>> 

2) En el código original, el corchete después de first_lst ) está fuera de lugar. Si colocamos ese corchete después del sec[0] lugar de la comprensión de la lista, obtenemos la expresión del generador . Y eso causará el mensaje :

 >>> [((fir[0],fir[1]*float(sec[1]),fir[2]*float(sec[2])) for fir in first_lst for sec in second_lst if fir[0] == sec[0])] # generator object [ at 0x00000184EEDE29E8>] 

En términos de syntax, la única diferencia es que uno usa paréntesis en lugar de corchetes.

Nota: Si es necesario, hay dos formas de convertir un objeto generador a la lista:

2a) Utilice el operador asterisco (*) para desempaquetar el objeto en la lista

 >>> [*((fir[0],fir[1]*float(sec[1]),fir[2]*float(sec[2])) for fir in first_lst for sec in second_lst if fir[0] == sec[0])] [('-2.50', 0.9359, 1.0555999999999999), ('-2.00', 0.9516000000000001, 1.04)] >>> 

2b) Usar explícitamente list()

 >>> list((fir[0],fir[1]*float(sec[1]),fir[2]*float(sec[2])) for fir in first_lst for sec in second_lst if fir[0] == sec[0]) [('-2.50', 0.9359, 1.0555999999999999), ('-2.00', 0.9516000000000001, 1.04)] >>>