列表过滤与转换

10 投票
8 回答
6066 浏览
提问于 2025-04-15 15:37

我有一个库文件名的列表,我需要用正则表达式来筛选这些文件名,然后从匹配的文件名中提取版本号。这是一个明显的做法:

libs = ['libIce.so.33', 'libIce.so.3.3.1', 'libIce.so.32', 'libIce.so.3.2.0']
versions = []
regex = re.compile('libIce.so\.([0-9]+\.[0-9]+\.[0-9]+)')
for l in libs:
    m = regex.match(l)
    if m:
        versions.append(m.group(1))

这样会生成以下列表:

['3.3.1', '3.2.0']

不过我觉得这个循环写得不是很“Python 风格”,感觉应该可以用一些聪明的单行代码来替代上面的“for”循环。有什么建议吗?

8 个回答

5

你可以这样做:

versions = [m.group(1) for m in [regex.match(l) for l in libs] if m]

不过我觉得这样写不太容易理解...

也许分成两步来做会更清楚:

matches = [regex.match(l) for l in line]
versions = [m.group(1) for m in matches if m]
8

再来一个简短的例子,给大家展示其他的方法(我也稍微简化了一下正则表达式):

regex = re.compile(r'^libIce\.so\.([0-9]+\.[0-9]+\.[0-9]+)$')
sum(map(regex.findall, libs), [])

不过要注意,你最开始的版本比所有建议的都更容易理解。这样改动值得吗?

19

你觉得用列表推导式怎么样?

In [5]: versions = [m.group(1) for m in [regex.match(lib) for lib in libs] if m] 
In [6]: versions
Out[6]: ['3.3.1', '3.2.0']

撰写回答