Возврат списка слов из списка строк с регулярным выражением - PullRequest
0 голосов
/ 06 апреля 2010

Я запускаю следующий код в списке строк, чтобы вернуть список его слов:

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 ]

4 голосов
/ 06 апреля 2010
>>> 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 голос
/ 06 апреля 2010

Причина, по которой вы получаете список списков, заключается в том, что re.split () возвращает список, который затем «добавляется» к выводу для понимания списка.просто плохой пример), но если вы можете получить весь контент (все строки) в виде строки, вы можете просто сделать

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

, если строки являются результатом:

open('filename').read()

вместо.

0 голосов
/ 09 августа 2011

Просто наткнулся на этот старый вопрос, и я думаю, что у меня есть лучшее решение.Обычно, если вы хотите вложить понимание списка («добавить» каждый список), вы думаете об обратном (не для цикла).Это не то, что вам нужно:

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

Однако, если вы хотите «расширить» вместо «добавления» списки, которые вы генерируете, просто пропустите дополнительный набор квадратных скобок и отмените своициклы (возвращая их в «правильном» порядке).

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

Мне кажется, это более Pythonic решение, так как оно основано на логике обработки списка, а не на какой-то встроенной функции со случайной задницей,Каждый программист должен знать, как это сделать (особенно те, кто пытается изучать Лисп!)

0 голосов
/ 06 апреля 2010

Вы всегда можете сделать это:

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

Это не так элегантно, как понимание списка из одной строки, но оно выполняет свою работу.

...