【问题标题】:Meaning of a python statement with "next( c for c in l if )"带有“next(c for c in l if)”的python语句的含义
【发布时间】:2018-04-15 16:06:54
【问题描述】:

在将一些 python 代码移植到 PHP 中时,我遇到了以下代码的问题:

def getOrAdd(self, config):
    h = config.hashCodeForConfigSet()
    l = self.configLookup.get(h, None)
    if l is not None:
        r = next((c for c in l if config.equalsForConfigSet(c)), None)
        if r is not None:
            return r
    if l is None:
        l = [config]
        self.configLookup[h] = l
    else:
        l.append(config)
    return config

我想不通,那一行是什么

r = next((c for c in l if config.equalsForConfigSet(c)), None)

确实是这个意思。

谁能解释一下这句话的含义?

提前谢谢你!

【问题讨论】:

  • 在本例中,next 只是获取推导式的第一个值,如果为空,则为 None

标签: python generator next generator-expression


【解决方案1】:

它将two-arg next(它从迭代器中提取下一个值,如果迭代器用尽,则返回第二个参数作为默认值)与generator expression 相结合,这就像一个懒惰的list 理解(它产生按需生成值的迭代器/生成器)。

所以:

r = next((c for c in l if config.equalsForConfigSet(c)), None)

在英文中,意思是“获取l的第一个元素,该元素的config.equalsForConfigSet为真;如果没有找到这样的元素,则返回None”。它会懒惰地执行此操作,或者如果您愿意,可以使用短路,因此只要一个 c 值通过,它就不需要继续; l 的其余部分甚至都没有加载,更不用说经过测试了(不像列表理解会这样做)。

在代码中,您可以使用如下函数表达相同的行为:

def firstEqualsConfigSet(l, config):
    for c in l:
        if config.equalsForConfigSet(c):
            # Short-circuit: got one hit, return it
            return c
    # Didn't find anything
    return None  # Redundant to explicitly return None, but illustrating
                 # that two-arg next could use non-None default

然后使用函数来做:

r = firstEqualsConfigSet(l, config)

【讨论】:

  • 你超级快@ShadowRanger :)
【解决方案2】:

我的理解是

下一个(迭代器,默认) next() 函数从迭代器中返回下一项。

它从 for 循环中获取“c”,该循环从列表 l(之前填充的)中提取 c,其中 for 循环正在评估 config.equalsForConfigSet(C) 应该返回 true 的条件。

如果next()的第一个参数中没有'c'的值,它将返回None

https://www.programiz.com/python-programming/methods/built-in/next

【讨论】:

    【解决方案3】:

    这基本上是对带有两个参数的next 函数的调用:

    • 生成器理解 - (c for c in l if config.equalsForConfigSet(c))
    • None

    所以让我们把它撕成碎片。

    理解部分

    括号() 中的内容是generator expression。就像列表推导式(与[] 一起使用时),但结果是生成器对象。

    感谢 @ShadowRanger 在 cmets 中的提示。

    nextNone

    next 函数返回给定迭代器中的下一项(在您的情况下为生成器表达式)。然而,当迭代器已经结束,并且没有其他东西可以返回时,它会引发StopIteration 异常。但是在这种情况下,当您将第二个参数作为默认值传递时,它会被返回而不是引发异常。因此,在您的情况下,如果发生后一种情况,则返回 None

    总结

    这整件事是为了以下几点:

    • 生成器是按需生成值的迭代器,因此不会将所有列表加载到内存中
    • next 调用会从您的全新生成器中获取第一个元素(如果有的话),否则 None

    所以如果我们描述源函数,它听起来像这样:

    l 中取出满足config.equalsForConfigSet 条件的第一个元素(如果有),否则返回None

    【讨论】:

    • 迂腐点:在括号中,[],这是一个列表理解。在括号中,(),它被称为生成器表达式。这不是“生成生成器实例的列表理解”。这些是官方术语,用一个来表示另一个会让人感到困惑。
    • 没错,就是为了指出。将添加更多链接。
    • 现在我知道了,要了解更多关于迭代器和生成器的信息,应该搜索什么。
    猜你喜欢
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多