【问题标题】:List comprehension for extracting re.findall matches提取 re.findall 匹配的列表理解
【发布时间】:2017-11-17 06:05:12
【问题描述】:

我有一个带有单个组的正则表达式,我想使用它将字符串列表映射到匹配的字符串的过滤匹配列表。目前,我正在使用以下内容:

matches = (re.findall(r'wh(at)ever', line) for line in lines)
matches = [m[0] for m in matches if m]

我怎样才能更优雅地做到这一点,只使用过滤器、地图和理解?显然,我可以使用 for 循环,但我想知道它是否可以纯粹通过操作迭代器来完成。

【问题讨论】:

  • 在这里只操作迭代器,你只是在寻找一个单线?
  • matches = [m[0] for m in (re.findall(r'wh(at)ever', line) for line in lines) if m]
  • 您可以使用from functools import partialfrom operator import itemgetter 并拥有非常实用的list(map(itemgetter(0), filter(None, map(partial(re.findall, r'wh(at)ever'), lines)))) ...但我仍然认为您的原始构造更优雅。
  • 如果你只想要第一项,为什么要使用re.findall
  • @CasimiretHippolyte 有更好的选择吗?如果是这样,请告诉我:)

标签: python regex functional-programming iterator generator


【解决方案1】:

使用映射、过滤器或其他功能技巧来混淆您的代码并没有真正的优势,因为列表理解快速、简单且清晰:

import re

lines = ['wh1atever wh1btever', 'wh2atever', '', 'wh4atever wh4btever wh4ctever']

'''Since you only want the first item for each line,
   using re.findall is a waste of time, re.search is more appropriate'''

pat1 = re.compile(r'wh(..)tever')
res1 = [ m.group(1) for m in (pat1.search(line) for line in lines) if m ]

print(res1)
'''['1a', '2a', '4a']'''


'''or if there are few lines, you can join them and use re.findall this time,
   with a pattern that consumes the end of the line'''

pat2 = re.compile(r'wh(..)tever.*')
res2 = pat2.findall("\n".join(lines))

print(res2)
'''['1a', '2a', '4a']'''

【讨论】:

  • 我说的是“地图、过滤器和理解” :) 我最喜欢这个!我会把m.group(1)放在一行,for m in ()放在下一行,if m放在第三行。
【解决方案2】:

您可以使用地图和过滤器。这是一种方法。

matches = map(lambda x: x[0], filter(None, map(lambda x: re.findall(r'wh(at)ever', x), lines)))

如果您使用的是 python3,请不要忘记在末尾添加 list(...)

但是,我认为这里不需要更多“优雅”。你所做的一切都很好。


另一种礼貌@juanpa.arrivillaga:

from functools import partial
list(map(itemgetter(0), filter(None, map(partial(re.findall, r'wh(at)ever'), lines))))

【讨论】:

  • 一行 >>>>>> 两行
  • 我认为你可以简单地用None 代替lambda x:x 来代替filter,因为我实际上使用过滤器而不是理解器已经很久了
  • 一行往往不如两行。这是一个很好的例子。
  • @Coldspeed 另外,这不起作用。结果将是单例字符串列表,而不是字符串列表。
  • partially applies the function。但是,是的,这一切都将基本相同。只是装扮不同,而且很可能比原来的版本更难读。
猜你喜欢
  • 2015-01-28
  • 2021-02-03
  • 2016-03-09
  • 2020-01-12
  • 1970-01-01
  • 1970-01-01
  • 2022-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多