2010-03-12 38 views
37

我有一个函数从字符串列表挑选出肿块,并返回它们作为另一个列表使用重新匹配对象:如何在列表理解

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')] 

回答

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

的“绝招”是for m in [regex.search(l)]的一部分 - 这就是你如何“分配”,你需要使用一个值不止一次,在列表理解中 - 添加一个这样的子句,其中的对象“遍历”包含您想要“分配”给它的一个值的单个项目列表。有些人认为这在风格上可疑,但我觉得有时候很实用。

+1

亚历克斯,我喜欢那样;感谢和+1。我有一些相当繁重的工作来处理这段代码 - 我是否应该担心设置和拆除“虚拟迭代器”的额外开销?顺便说一句,我赞成“稍后优化”的原则。 – 2010-03-13 00:12:57

+1

@Brent,对于搜索调用,“虚迭代器”应该可以忽略不计;一个较小的优化是使用'(regex.search(l),'''代替'[regex.search(l)]'(我发现它更易读,但速度更慢 - 我认为你不可能是因为你实际上正在调用模块的're.search'函数,而不是re对象的方法。将'regex.search'作为listcomp之外的绑定方法拉动是另一个次要但有用的优化,顺便提一下, – 2010-03-13 01:15:07

+0

as当我看到你的答案时,我意识到使用re.search并不是最好的方法,你能否澄清一下你如何“将regex.search作为listcomp之外的绑定方法”?我真的很感激你对listcomp和Python noob的耐心等待 – 2010-03-13 10:08:31

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

它可以缩短一点

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

你可以把它全部在同一行,但也意味着你将不得不每行曾两次将是一个有点低效率的匹配。

+2

不需要每行两次匹配,请参阅我的答案。 – 2010-03-12 23:59:27

+0

事实上,你的答案是更清洁,从我+1 +1 – Wolph 2010-03-13 00:01:23

-13
>>> "a" in "a visit to the dentist" 
True 
>>> "a" not in "a visit to the dentist" 
False 

,也可用于你正在追捕列表中的

'P = 'A', 'B' 搜索查询, 'C'

'B' 的P`返回true

+1

这是如何回答这个问题? – 2012-11-17 19:20:38

+0

这个问题可能会提供一个比re更好的方法来检查列表中的输入,但是如果你不想grep结果,那么这种方法不起作用。 U总是可以为重新输出做一个简单的循环。手动操作比使用同样功能的功能差异不大 – erm3nda 2016-05-17 16:41:08