【问题标题】:Iterator inside for-loop: why is this not working?for循环内的迭代器:为什么这不起作用?
【发布时间】:2014-02-28 12:40:20
【问题描述】:

我有这段代码,它不起作用,我不知道为什么。

我的数据结构:

  • "genes" 是一个字典,它的 ID 作为键,作为值的倍数 对象 Gene 的实例。
  • Gene 对象包含一个类似的字典,其中包含 对象“成绩单”。

最后,“parent”是一个 Transcript(字符串)的 ID。 我需要获取与字符串“parent”具有相同 ID 的 Transcript 实例 (ptrans)。 它位于其中一个 Gene 实例中。

当我在底部运行代码时,我没有得到一个真正的异常,而是一个“StopIteration”,我认为我捕获了它,然后它应该继续下一个 Gene 对象,对吗?:

Traceback (most recent call last): File "<stdin>", line 1, in <module> ... ptrans = next(t for t in g.transcripts.values() if t.ID == parent) StopIteration

我可以使用嵌套的 for 循环来做到这一点,但我认为这也可以。我只是无法理解这不起作用的事实。谁能解释一下为什么,或者它是如何工作的?

    # iterate over Gene-dict
    for g in genes.values(): 
        #Iterate over Transcripts in 1 Gene
        try:
            ptrans = next(t for t in g.transcripts.values() if t.ID == parent)
        #If no match, continue
        except StopIteration:
            continue
        if ptrans:
                break

【问题讨论】:

  • 看来你应该抓住它了。你可以发布一个minimal runnable example 来演示运行时的问题吗?在剥离代码和回溯时,您似乎隐藏了错误的原因。
  • 您的回溯未显示您的代码具有的 try 块。
  • 你为什么要在那里休息? break 将停止 for 循环,因此它看起来一旦成功运行一次就会停止。这是故意的吗?
  • continue “切断”当前迭代并从下一项开始。因此,如果 ptrans 被定义,则没有 StopIteration,这意味着它已经找到了 ID,然后它可以跳出 for 循环。
  • next() 有一个可选的second parameter,这意味着您可以执行if next(iter, None) is None 而不是捕获StopIteration 异常。

标签: python loops for-loop iterator


【解决方案1】:

你的代码

ptrans = next(t for t in g.transcripts.values() if t.ID == parent)

几乎可以肯定没有按照你的想法做。我怀疑g.transcript.values() 中没有以父项为 ID 的项目,因为在空生成器上调用 next() 确实会引发 StopIteration 错误。

然而,next() 函数在任何情况下都只会被调用一次,这意味着即使存在 个有效值,也只会返回第一个值。嵌套循环是实现您想要做的事情的一种更简单的方法。

【讨论】:

  • 谢谢,我已经在 v1 中得到了,但我认为这种方式会更优雅。
  • 为什么?我想说代码的优雅应该从正确的操作开始。我为你学习的愿望鼓掌,但你在生成器方面还有很长的路要走。
  • @holdenweb - 实际上,我一直使用这种结构。这是一种在一行中实现自定义查找算法的好方法。无论如何,他只是在寻找第一个实例(而且,听起来,只期待一个实例)。
  • ID 是唯一的,所以是的,我只希望检索一份成绩单。但我想我的代码在其他地方有错误。
猜你喜欢
  • 2013-12-13
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 2018-03-16
  • 2010-10-17
相关资源
最近更新 更多