有没有办法让这段代码更简洁?

1 投票
3 回答
609 浏览
提问于 2025-04-17 04:03

给定一个物品列表,还有一个从条件函数到“值”函数的映射,下面的代码会对满足相应条件的物品应用“值”函数:

my_re0 = re.compile(r'^([a-z]+)$')
my_re1 = re.compile(r'^([0-9]+)$')
my_map = [
    (my_re0.search, lambda x: x),
    (my_re1.search, lambda x: x),
    ]
for x in ['abc','123','a1']: for p, f in my_map: v = p(x) if v: print f(v.groups()) break

有没有办法用一句话来表达同样的意思呢?

如果我不需要把条件函数返回的值传给“值”函数,那我可以这样做:

for x in ['abc','123','a1']:
    print next((f(x) for p, f in my_map if p(x)), None)

那么对于上面的代码,有没有类似的做法呢?我知道,也许保留这些嵌套的循环更好,但我只是好奇是否有可能。

3 个回答

0

这是我的版本:

for x in ['abc','123','a1']:
    print next((f(v.groups()) for p, f in my_map for v in [p(x)] if v), None)
这个版本不会遍历整个 my_map,而是一找到第一个成功的匹配就停止了。

1
[f(v.groups()) for x in ['abc','123','a1'] for p, f in my_map for v in [p(x)] if v]

你说要更简洁,对吧?;^)

2

比Nate的解释稍微详细一些;-)

from itertools import product

comb = product(my_map, ['abc','123','a1'])
mapped = ((p(x),f) for (p,f),x in comb)
groups = (f(v.groups()) for v,f in mapped if v)
print next(groups), list(groups) # first match and the rest of them

撰写回答