【问题标题】:In Python, how can I refer to a return-value from a function called within a generator expression?在 Python 中,如何引用生成器表达式中调用的函数的返回值?
【发布时间】:2012-01-19 01:52:03
【问题描述】:

简化,我想做这样的事情:

({'publication': obj.pub_name, 'views': obj.views, } for obj = analyze_publication(p) for p in Publication.objects.all())

当然,这是行不通的。

现在,我正在使用:

({'publication': obj.pub_name, 'views': obj.views, } for obj in (analyze_publication(p) for p in Publication.objects.all()))

我不知道第二个代码段是如何完成的,还是有其他语法,或者效率不高等。我才 2 周进入 Python。

【问题讨论】:

  • 请问您的第二个样品有什么问题?它在 Python 中是正确的并产生你想要的结果?!
  • @gecco:没问题 x__x,只是完全没有经验。在我未经训练的眼睛里,第二个看起来像循环内循环......如果那些是偶数循环的话。我只是想知道这是否是一种明显低效的方式等等。
  • 我明白了……实际上是有趣的挑战。除了在循环中使用单独的函数构造 dict 之外,我没有看到其他解决方案:(toDict(analyze_publication(p)) for p in Publication.objects.all())

标签: python syntax generator-expression


【解决方案1】:

与其试图扭曲生成器表达式语法以允许名称绑定,不如使用一个函数来生成绑定。那么就很简单了:

def pubdict(pub):
    obj = analyze_publication(pub)
    return {"publication": obj.pub_name, "views": obj.views}

itertools.imap(pubdict, Publication.objects.all()

【讨论】:

    【解决方案2】:

    有不平衡的括号,但除此之外,嵌套生成器表达式应该没有(功能)问题。与列表推导一样,它们在嵌套时很快就会变得笨拙。为了便于阅读,我建议将其移至命名生成器。

    如果您对性能感到好奇,请使用disassemblerprofilers 比较不同的方法。

    【讨论】:

      【解决方案3】:

      只是另一个版本:

      ( dict(publication= obj.pub_name, views= obj.views) 
          for obj in map(analyze_publication, Publication.objects.all()) )
      

      【讨论】:

      • 看起来很时尚!它的表现是否相同? (抱歉,我的思维还没有适应 Python 语法)
      • docs.python.org/library/functions.html#map 表示 map 返回一个列表(在 Python3 中它是一个 map 对象 - 也是一种生成器),而 for obj in (...) 返回一个生成器。所以我认为map 的表现可能会更差。但我认为它只适用于非常大的列表。无论如何,在进行任何优化之前 - 1. 确保它正常工作 2. 进行一些分析以确保这是瓶颈。
      • map 替换为itertools.imap 以获得迭代器而不是列表。
      猜你喜欢
      • 1970-01-01
      • 2013-06-17
      • 2021-04-07
      • 2010-12-09
      • 2021-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-15
      相关资源
      最近更新 更多