如何在列表推导中使用正则匹配对象

47 投票
5 回答
78774 浏览
提问于 2025-04-15 20:22

我有一个函数,它可以从一串字符串中挑出特定的部分,并把这些部分放到另一个列表里:

def filterPick(lines,regex):
    result = []
    for l in lines:
        match = re.search(regex,l)
        if match:
            result += [match.group(1)]
    return result

有没有办法把这个改写成列表推导式?现在的写法已经很清晰了,只是出于好奇想知道。


感谢那些提供帮助的人,特别感谢@Alex。下面是我最后得到的简化版本;正则匹配的方法作为一个“预先提升”的参数传递给了filterPick:

import re

def filterPick(list,filter):
    return [ ( l, m.group(1) ) for l in list for m in (filter(l),) if m]

theList = ["foo", "bar", "baz", "qurx", "bother"]
searchRegex = re.compile('(a|r$)').search
x = filterPick(theList,searchRegex)

>> [('bar', 'a'), ('baz', 'a'), ('bother', 'r')]

5 个回答

7

可以稍微简化一下

def filterPick(lines, regex):
    matches = map(re.compile(regex).match, lines)
    return [m.group(1) for m in matches if m]

你可以把它放在一行里,但这样的话你就得每一行都匹配两次,这样效率就会低一些。

12
return [m.group(1) for m in (re.search(regex, l) for l in lines) if m]

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

79
[m.group(1) for l in lines for m in [regex.search(l)] if m]

这里的“窍门”就是 for m in [regex.search(l)] 这一部分——这就是你如何在列表推导式中“赋值”一个需要多次使用的值的方法。你只需添加这样一个条件,让这个对象在一个只包含你想要“赋值”的单个值的列表中“迭代”。有些人觉得这样写风格上不太好,但我觉得在某些情况下这样做很实用。

撰写回答