我有一个函数从字符串列表中挑出块并将它们作为另一个列表返回:
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')]
答案 0 :(得分:69)
[m.group(1) for l in lines for m in [regex.search(l)] if m]
“技巧”是for m in [regex.search(l)]
部分 - 这就是你如何“分配”一个你需要多次使用的值,在列表理解中 - 添加这样一个子句,其中对象“迭代“在包含您想要”分配“它的一个值的单项列表上。有些人认为这在风格上是可疑的,但有时我觉得它很实用。
答案 1 :(得分:10)
return [m.group(1) for m in (re.search(regex, l) for l in lines) if m]
答案 2 :(得分:7)
可以缩短一点
def filterPick(lines, regex):
matches = map(re.compile(regex).match, lines)
return [m.group(1) for m in matches if m]
你可以将它全部放在一行中,但这意味着你必须将每一行匹配两次才会效率低一些。
答案 3 :(得分:1)
从Python 3.8
开始,并引入assignment expressions (PEP 572)(:=
运算符),可以在列表推导中使用局部变量,以避免多次调用同一表达式:
# items = ["foo", "bar", "baz", "qurx", "bother"]
[(x, match.group(1)) for x in items if (match := re.compile('(a|r$)').search(x))]
# [('bar', 'a'), ('baz', 'a'), ('bother', 'r')]
此:
re.compile('(a|r$)').search(x)
的评估命名为变量match
(可以是None
或Match
对象)match
命名表达式(None
或Match
)来过滤不匹配的元素match
)在映射值中重新使用match.group(1)
。答案 4 :(得分:-14)
>>> "a" in "a visit to the dentist"
True
>>> "a" not in "a visit to the dentist"
False
这也适用于您在列表中搜索的搜索查询
`P ='a','b','c'
P`中的'b'返回true