【问题标题】:Python: Nested for loops or "next" statementPython:嵌套 for 循环或“下一个”语句
【发布时间】:2011-04-08 14:17:58
【问题描述】:

我是一个菜鸟爱好者,我在写python的时候会嵌套for循环,像这样:

dict = {
    key1: {subkey/value1: value2} 
    ... 
    keyn: {subkeyn/valuen: valuen+1}
    }

for key in dict:
    for subkey/value in key:
       do it to it

我知道一个“下一个”关键字可以在一行中实现相同的目标(我问了一个关于如何使用它的问题,但我不太明白)。

所以对我来说,嵌套的 for 循环更具可读性。为什么,那么人们使用“下一个”?我在某处读到 Python 是一种动态类型和解释的语言,因为 + 既连接字符串又对数字求和,它必须检查每次循环迭代的变量类型,以便知道运算符是什么等。使用“next”是否会阻止这在某种程度上加快了执行速度,还是只是风格/偏好的问题?

【问题讨论】:

    标签: python optimization for-loop


    【解决方案1】:

    next 对于推进迭代器在必要时 是很宝贵的,而该推进不控制显式的for 循环。例如,如果您想要“S 中大于 100 的第一项”,next(x for x in S if x > 100) 将把它给您,没有麻烦,没有大惊小怪,没有不必要的工作(因为一旦找到合适的x,一切都会终止) - 如果意外地没有 x 匹配条件,您会得到一个异常 (StopIteration)。如果预期不匹配并且您在这种情况下需要None,则next((x for x in S if x > 100), None) 将提供。出于这个特定目的,如果 next 实际上被命名为 first,您可能会更清楚,但这会暴露其更普遍的用途。

    例如,考虑合并多个序列的任务(例如,排序序列的并集或交集——例如,排序文件,其中项目是行)。同样,next 正是医生所要求的,因为没有一个序列可以通过控制 A“主 for 循环”来支配其他序列。因此,为了简单起见,假设不存在重复项(如果需要,这种情况不难放松),您将配对 (currentitem, itsfile) 保留在由 heapq 控制的列表中,合并变得容易......但这要归功于魔法的next 在其项目被使用后推进正确文件,并且仅限该文件。

    import heapq
    
    def merge(*theopentextfiles):
        theheap = []
        for afile in theopentextfiles:
            theitem = next(afile, '')
            if theitem: theheap.append((theitem, afile))
        heapq.heapify(theheap)
        while theheap:
            theitem, afile = heapq.heappop(theheap)
            yielf theitem
            theitem = next(afile, '')
            if theitem: heapq.heappush(theheap, (theitem, afile))
    

    只要尝试在没有next...的情况下做任何如此优雅的事情!-)

    一个可以持续很长时间,但是这两个用例“将迭代器推进一个位置(不让它控制整个 for 循环)”和“只从迭代器中获取第一项”占next 的最重要用途。

    【讨论】:

    • +1 你又做了一次。我刚刚意识到我有用的 any aka first 可以定义(任何序列中的第一个非 False 或序列中的最后一个值,如果全部为 False)也可以用 next 和 iter 定义。
    • @Tony,对于 empty 序列,您的“有用的任何 aka first”返回什么?与[False][None] 或其他什么相同?顺便说一句,我认为next(itertools.ifilter(None, seq), None) 可能更实用(返回None 用于没有任何真实项目的 any 序列,包括空的和非空的......似乎更统一!)。
    • 我想出了相同的版本,但认为我的要求与next(itertools.ifilter(None, seq), type(seq)()) 最匹配。一致性很重要,我在想 Python á la Lisp (OR ...) 的短路 or 的一致性。由于 Python 有单独的 []、() 等,空序列的问题需要考虑。可能大多数 Pythonic 答案是在这种情况下留下下一个引发异常(下一个参数)。此外,正常功能非常干净,以至于在这种情况下 next 的好处是值得怀疑的,因为 for 在功能上做得很好。
    • 好的,谢谢。 Next 现在看起来好用了。我猜是添加了“,无”这让我感到震惊。
    • @aquateenfan,好点子——如果你希望避免迭代器的异常,你只需要, None(或, '',就像我在上面的例子中一样)耗尽(有时这种耗尽是出乎意料的,最好变成异常,有时完全可以预料,最好通过其他方式处理)。
    猜你喜欢
    • 2019-04-22
    • 2019-06-05
    • 2015-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多