web-dev-qa-db-fra.com

Obtenir <objet générateur <genexpr>

J'ai 2 listes:

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')]

Je veux faire le calcul suivant pour cela:

Multipliez 0.49 par 1.91 (les valeurs correspondantes de first_lst et second_lst), puis multipliez 0.52 par 2.03 (valeurs correspondantes également). Je veux le faire à condition que les valeurs à la position 0 dans chaque tuple correspondant soient identiques, donc -2.50 == -2.50 etc. De toute évidence, nous faisons le même calcul pour la modification des n-uplets. 

Mon code:

[((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]]

Génère cependant un objet:

[<generator object <genexpr> at 0x0223E2B0>]

Pouvez-vous m'aider à réparer le code? 

8
nutship

Vous devez utiliser Tuple() ou list() pour convertir cette expression génératrice en une variable list ou 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]]

Version de travail de votre code:

>>> 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)]
14

Considérant que vos first_lst et second_lst sont définis comme suit.

>>> 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 compréhension de la liste suivante peut être utile.

>>> [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)]
1
Sukrit Kalra

Il y a 2 problèmes à examiner.

Le code d'origine générera l'erreur:

>>> 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 "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
NameError: name 'fir' is not defined
>>>

et le message <generator object <genexpr> est mentionné. 

1) Corrigeons le code avec un minimum de modifications en créant liste compréhension :

>>> 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) Dans le code d'origine, la parenthèse après first_lst) est mal placée. Si nous plaçons cette parenthèse après le sec[0] au lieu de la compréhension de liste, nous obtenons générateur d'expression . Et cela provoquera le message <generator object <genexpr>

>>> [((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
[<generator object <genexpr> at 0x00000184EEDE29E8>]

En termes de syntaxe, la seule différence est que l'on utilise des parenthèses au lieu de crochets.

Remarque: Si nécessaire, il existe deux manières de convertir un objet générateur en liste:

2a) Utilisez l'opérateur astérisque (*) pour décompresser un objet dans la liste

>>> [*((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) Utiliser explicitement 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)]
>>>
0
sg7