【问题标题】:Variable scope in a Python generator expressionPython 生成器表达式中的变量范围
【发布时间】:2014-07-19 09:48:03
【问题描述】:

我已经编写了一个函数来创建一个字典映射字符串 -> 生成器表达式。生成器表达式根据两个条件过滤项目列表,这两个条件对于字典中的每个生成器都是不同的。

def iters(types):
    iterators = {}
    for tname in types:
        inst, type = tname.split('|')
        iterators[tname] = (t for t in transactions() if t['institution_type'] == inst and t['type'] == type)
    return iterators

我遇到的问题是所有生成器都根据insttype 的最后一个值进行过滤,大概是因为这两个变量在循环的每次迭代中都被重复使用。我该如何解决这个问题?

【问题讨论】:

    标签: python python-2.7 scope generator


    【解决方案1】:

    是的,insttype 名称用作 闭包;当您迭代生成器时,它们已绑定到循环中的最后一个值。

    为名称创建一个新范围;一个函数可以做到这一点:

    def iters(types):
        def build_gen(tname):
            inst, type = tname.split('|')
            return (t for t in transactions()
                    if t['institution_type'] == inst and t['type'] == type)
        iterators = {}
        for tname in types:
            iterators[tname] = build_gen(tname)
        return iterators
    

    你也可以用字典理解替换最后几行:

    def iters(types):
        def build_gen(tname):
            inst, type = tname.split('|')
            return (t for t in transactions() 
                    if t['institution_type'] == inst and t['type'] == type)
        return {tname: build_gen(tname) for tname in types}
    

    【讨论】:

    • 我不确定 closure 是否是正确的词,感谢您澄清这一点。我试图确定是否可以在 python 中创建某种范围变量而不必创建新函数
    • @Stankalank:是的,insttype 在名称上是封闭的。
    • 跟进问题,insttype 是否也会在字典理解中关闭名称?我想这就是这种情况。像这样的东西似乎遇到了与 for 循环相同的问题:{inst: (t for t in trans if t['something'] > 0) for inst, trans in some_dictionary}
    • @Stankalank:是的,生成器表达式、字典推导和集合推导在新范围内执行。列表推导不是,但仅在 Python 2.x 中。在 Python 3 中,它们都使用了新的作用域。列表推导首先被添加到语言中,直到后来添加更多推导和生成器表达式时,才发现使用单独的范围是一个更好的主意。
    猜你喜欢
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 2018-05-02
    • 2017-12-08
    • 1970-01-01
    • 2014-04-02
    相关资源
    最近更新 更多