Регулярные выражения: поиск в списке

87

Я хочу фильтровать строки в списке на основе регулярного выражения.

Есть что-нибудь лучше [x for x in list if r.match(x)]?

леолук
источник

Ответы:

114

Вы можете создать итератор в Python 3.x или список в Python 2.x, используя:

filter(r.match, list)

Чтобы преобразовать итератор Python 3.x в список, просто приведите его; list(filter(..)).

sepp2k
источник
2
На самом деле, понимание списков обычно предпочтительнее функциональных конструкций, таких как фильтр, сокращение, лямбда и т. Д.
Иво ван дер Вейк,
37
@Ivo: Их обычно предпочитают, потому что они обычно более четкие и часто более лаконичные. Однако в этом случае filterверсия совершенно четкая и имеет гораздо меньше шума.
sepp2k 04
9
что r.matchздесь?
rbatt
2
@rbatt r.match- это метод, который при применении к заданной строке определяет, соответствует ли регулярное выражение rэтой строке (и возвращает соответствующий объект соответствия, если это так, но в данном случае это не имеет значения, поскольку нам просто важно, является ли результат правдивым)
sepp2k
167

Полный пример (Python 3):
для Python 2.x см. Примечание ниже

import re

mylist = ["dog", "cat", "wildcat", "thundercat", "cow", "hooo"]
r = re.compile(".*cat")
newlist = list(filter(r.match, mylist)) # Read Note
print(newlist)

Печать:

['cat', 'wildcat', 'thundercat']

Заметка:

Для разработчиков Python 2.x уже filterвозвращает список. В Python 3.xfilter было изменено возвращать итератор, поэтому его нужно преобразовать в list(чтобы он хорошо распечатался).

Пример кода Python 3 Пример кода
Python 2.x

Меркурий
источник
4
Привет, когда я запускаю приведенный выше код, я получаю « <filter object at 0x1057acda0>Что я делаю не так?»
1
Согласно документации python (python 2.7.12): docs.python.org/2/library/functions.html#filter фильтр возвращает список, а не объект. Вы также можете проверить этот код: repl.it/X3G/5786 (просто нажмите " Выполнить" )
Mercury
1
Спасибо. Я использую Python 3.5.2 на Mac. Я пробовал вашу ссылку. Конечно, это работает, хотя я не знаю, почему я получаю это сообщение. Я даже удалил, strпоскольку filterвозвращает список, но безрезультатно ...
4
@joshua вы, наверное, уже догадались, но попробуйте print(list(newlist))илиprint([i for i in newlist])
Джеймс Дрейпер
1
Это до смешного сложно. Вот почему R лучше. Просто grep (pattern, vector_of_names)
MadmanLee
1

Чтобы сделать это без предварительной компиляции Regex, используйте lambdaфункцию, например:

from re import match

values = ['123', '234', 'foobar']
filtered_values = list(filter(lambda v: match('^\d+$', v), values))

print(filtered_values)

Возврат:

['123', '234']

filter()просто принимает в callableкачестве первого аргумента и возвращает список, в котором этот вызываемый объект вернул истинное значение.

Коллин Хейст
источник