Pythonic方式在if语句中重写赋值

5 投票
7 回答
1158 浏览
提问于 2025-04-16 04:19

有没有一种在Python中更优雅的写法,能做到我在C++中做的事情:


for s in str:
    if r = regex.match(s):
        print r.groups()

我真的很喜欢那种写法,我觉得它比到处使用临时变量要干净很多。唯一一个不太复杂的其他写法是


for s in str:
    r = regex.match(s)
    if r:
        print r.groups()

我想我是在抱怨一个比较小的问题。我只是怀念以前的写法。

7 个回答

1

这里有一个方法可以实现赋值表达式,但这个方法有点不太靠谱。你提到的第一个选项是不能编译的,所以第二个选项才是可行的。

## {{{ http://code.activestate.com/recipes/202234/ (r2)
import sys
def set(**kw):
    assert len(kw)==1

    a = sys._getframe(1)
    a.f_locals.update(kw)
    return kw.values()[0]

#
# sample
#

A=range(10)

while set(x=A.pop()):
    print x
## end of http://code.activestate.com/recipes/202234/ }}}

正如你所看到的,生产环境中的代码最好不要碰这种黑科技,离它远点。

2

这可能有点不太正规,但可以利用函数对象的属性来存储最后的结果,这样你就可以做到类似下面这样的事情:

def fn(regex, s):
    fn.match = regex.match(s) # save result
    return fn.match

for s in strings:
    if fn(regex, s):
        print fn.match.groups()

或者更通用一点:

def cache(value):
    cache.value = value
    return value

for s in strings:
    if cache(regex.match(s)):
        print cache.value.groups()

需要注意的是,虽然保存的“值”可以是很多东西的集合,但这种方法一次只能保存一个值。所以如果你需要同时保存多个值,比如在嵌套函数调用、循环或其他线程中,可能就需要多个函数来处理这种情况。因此,按照DRY原则,干脆不写重复的代码,可以用一个工厂函数来帮助你:

def Cache():
    def cache(value):
        cache.value = value
        return value
    return cache

cache1 = Cache()
for s in strings:
    if cache1(regex.match(s)):
        # use another at same time
        cache2 = Cache()
        if cache2(somethingelse) != cache1.value:
            process(cache2.value)
        print cache1.value.groups()
          ...
10

这样怎么样呢

for r in [regex.match(s) for s in str]:
    if r:
        print r.groups()

或者可以稍微更具功能性一点

for r in filter(None, map(regex.match, str)):
    print r.groups()

撰写回答