返回带有正则表达式的行列表中的单词列表

时间:2010-04-06 16:05:06

标签: python regex python-3.x list-comprehension

我在字符串列表上运行以下代码以返回其单词列表:

words = [re.split('\\s+', line) for line in lines]

然而,我最终得到的结果如下:

[['import', 're', ''], ['', ''], ['def', 'word_count(filename):', ''], ...]

与期望相反:

['import', 're', '', '', '', 'def', 'word_count(filename):', '', ...]

如何解析上面列表理解中列出的re.split('\\s+', line)列表?天真地,我尝试使用*,但这不起作用。

(我正在寻找一种简单的Pythonic方式;我很想写一个函数,但我确信该语言可以适应这个问题。)

4 个答案:

答案 0 :(得分:4)

>>> import re
>>> from itertools import chain
>>> lines = ["hello world", "second line", "third line"]
>>> words = chain(*[re.split(r'\s+', line) for line in lines])

这将为您提供一个迭代器,可用于循环遍历所有单词:

>>> for word in words:
...    print(word)
... 
hello
world
second
line
third
line

创建列表而不是迭代器只是在list调用中包装迭代器的问题:

>>> words = list(chain(*[re.split(r'\s+', line) for line in lines]))

答案 1 :(得分:1)

你得到列表列表的原因是因为re.split()返回一个列表,然后“追加”到列表推导输出中。

目前还不清楚为什么要使用它(或者可能只是一个不好的例子),但是如果你可以将完整内容(所有行)作为一个字符串,你可以做到

words = re.split(r'\s+', lines)

如果行是以下产品:

open('filename').readlines()

使用

open('filename').read()

代替。

答案 2 :(得分:0)

您可以随时执行此操作:

words = []
for line in lines:
  words.extend(re.split('\\s+',line))

它不像单线列表理解那样优雅,但它完成了工作。

答案 3 :(得分:0)

偶然发现了这个老问题,我想我有更好的解决方案。通常,如果你想嵌套一个列表理解(“追加”每个列表),你会倒退(不像循环一样)。这不是你想要的:

>>> import re
>>> lines = ["hello world", "second line", "third line"]
>>> [[word for word in re.split(r'\s+', line)] for line in lines]
[['hello', 'world'], ['second', 'line'], ['third', 'line']]

但是,如果你想“扩展”而不是“追加”你正在生成的列表,只需省去额外的方括号并反转你的for循环(将它们放回“正确”的顺序)。

>>> [word for line in lines for word in re.split(r'\s+', line)]
['hello', 'world', 'second', 'line', 'third', 'line']

这对我来说似乎是一个更加Pythonic的解决方案,因为它基于列表处理逻辑而不是一些随机内置函数。每个程序员都应该知道如何做到这一点(特别是那些试图学习Lisp的人!)