【问题标题】:Getting <generator object <genexpr>获取 <generator object <genexpr>
【发布时间】:2013-04-28 17:12:56
【问题描述】:

我有 2 个列表:

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

我想对它做以下数学运算:

0.49 乘以1.91(来自first_lstsecond_lst 的对应值),并将0.52 乘以2.03(还有对应的值)。我想在每个相应元组中0 位置的值相同的条件下执行此操作,因此-2.50 == -2.50 等。显然,我们也对重新分配元组进行相同的数学运算。

我的代码:

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

生成一些对象:

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

你能帮我修复代码吗?

【问题讨论】:

  • 您的元组的 stringfloat 类型不匹配。这是故意的还是只是一个错误?如果您将这些作为元组,您的 LC 将失败。因为float 不能乘以string。请参阅我的答案以修复该错误。
  • 在意识到需要将所有内容转换为浮点数之前,我已经编写了这段代码。现在将对其进行编辑,以免混淆任何人。感谢您指出。
  • 好吧,Ashwini 的回答解决了这个问题。通常,当您使用列表推导式时,您必须将最终结果类型转换/存储到列表或元组中。

标签: python python-2.7 list-comprehension


【解决方案1】:

您需要使用tuple()list() 将该生成器表达式转换为listtuple

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

您的代码的工作版本:

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

【讨论】:

  • 奇怪的是,这段代码给出了fir is not defined. 错误。这是我这边的问题吗?
  • @SukritKalra 此 LC 中使用的名称与 OP 发布的名称不同。
  • 他的理解给出了同样的错误,而不是创建一个生成器对象。
  • @SukritKalra 您必须使用 first_lstsecond_lst 作为元组的变量名称。
  • 是的,我是。我不明白为什么这会导致 LC 失败。此外,OP 在float 中有一半的元组,在string 中有一半,因此,LC 将失败,您可以将string 显式转换为float
【解决方案2】:

考虑到您的first_lstsecond_lst 定义如下。

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

以下列表推导可能有用。

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

【讨论】:

  • 顺便说一句。为什么如果我想在末尾添加else 语句会引发错误invalid syntax。像这样:if elem[0][0]==elem[1][0] else pass] 这与我现在检查的 python 文档并不矛盾。
  • zip 仅适用于同一索引上的元素,如果我没有错,那么 OP 试图将任何两个元组相乘,整个第一个元素都是相同的。
  • 他说每个对应的元组,所以我认为他想处理具有相同索引的那些。
  • 要回答 OP 的问题,您可以这样做,只需将 for 语句放在末尾即可。像这样。 [tuple((float(elem[0][0]), float(elem[0][1])*float(elem[1][1]), float(elem[0][2])*float(elem[1][2]))) if elem[0][0]==elem[1][0] else '' for elem in zip(first_lst, second_lst)] 出于某种原因,passcontinue 不起作用,但无论如何您都不需要它们,如果您想跳过,LC 无论如何都会这样做。
【解决方案3】:

我遇到了同样的问题,并为您的问题找到了一个更简单的答案。 您唯一需要做的就是使用原始的 for 循环语法,它运行良好!

这是您的代码的工作版本:

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

打印(答案)

output=[['-2.50', 0.9359, 1.0555999999999999], ['-2.00', 0.9516000000000001, 1.04]]

【讨论】:

    【解决方案4】:

    有 2 个问题需要考虑。

    原代码会产生错误:

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

    &lt;generator object &lt;genexpr&gt; 消息被提及。

    1) 让我们通过创建list comprehension 以最少的更改来修复代码:

    >>> 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) 在原代码中,first_lst) 后面的括号放错了位置。 如果我们将括号放在sec[0] 之后而不是列表理解之后,我们会得到generator expression。这将导致&lt;generator object &lt;genexpr&gt; 消息:

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

    就语法而言,唯一的区别是使用括号而不是方括号。

    注意:如果需要,有两种方法可以将生成器对象转换为列表:

    2a) 使用星号 (*) 运算符将对象解包到列表中

    >>> [*((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) 明确使用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)]
    >>>
    

    【讨论】:

      【解决方案5】:

      您正在制作生成器,而不是元组或列表

      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]] 
      output:-[('-2.50', 0.9359, 1.0555999999999999), ('-2.00', 0.9516000000000001, 1.04)]
      

      【讨论】:

        猜你喜欢
        • 2020-01-11
        • 1970-01-01
        • 1970-01-01
        • 2018-05-11
        • 2016-04-29
        • 1970-01-01
        • 2014-06-17
        • 2022-08-11
        相关资源
        最近更新 更多