Регулярні вирази: пошук у списку


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(..)).


2
Насправді розуміння списків переважно перед функціональними конструкціями, такими як фільтр, зменшення, лямбда тощо
Іво ван дер Вайк,

37
@Ivo: Зазвичай їм надають перевагу, оскільки вони, як правило, чіткіші та часто більш лаконічні. Однак у цьому випадку filterверсія абсолютно чітка і має набагато менше шуму.
sepp2k

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 docs (python 2.7.12): docs.python.org/2/library/functions.html#filter фільтр повертає список, а не об'єкт. Ви також можете перевірити цей код: repl.it/X3G/5786 (щойно вдарив запуск)
Меркурій

1
Дякую. Я використовую Python 3.5.2 на Mac. Я спробував ваше посилання. Звичайно, це працює, хоча не впевнений, чому я отримую це повідомлення. Я навіть видалив, strоскільки filterповертає список у будь-якому випадку, безрезультатно ...

4
@joshua ти вже напевно це зрозумів, але спробуй print(list(newlist))абоprint([i for i in newlist])
Джеймс Дрейпер

1
Це смішно важко. Ось чому R вищий. Просто grep (візерунок, vector_of_names)
MadmanLee

1

Щоб зробити це без попереднього складання регулярного виразу, скористайтеся 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як перший аргумент і повертає список, де той, що викликається, повертає значення "істинно".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.