Biểu thức chính quy: Tìm kiếm trong danh sách


87

Tôi muốn lọc các chuỗi trong danh sách dựa trên một biểu thức chính quy.

Có cái gì tốt hơn [x for x in list if r.match(x)]không?

Câu trả lời:


114

Bạn có thể tạo một trình lặp trong Python 3.x hoặc một danh sách trong Python 2.x bằng cách sử dụng:

filter(r.match, list)

Để chuyển đổi trình lặp Python 3.x thành một danh sách, chỉ cần ép kiểu nó; list(filter(..)).


2
Trên thực tế, comprehensions danh sách thường được ưa thích hơn các cấu trúc chức năng như bộ lọc, giảm, lambda vv
Ivo van der Wijk

37
@Ivo: Chúng thường được ưa thích hơn vì chúng thường rõ ràng hơn và thường ngắn gọn hơn. Tuy nhiên trong trường hợp này, filterphiên bản hoàn toàn rõ ràng và ít nhiễu hơn nhiều.
sepp2k

9
cái gì r.matchở đây?
rbatt

2
@rbatt r.matchlà một phương thức, khi được áp dụng cho một chuỗi nhất định, sẽ tìm xem liệu regex có rkhớp với chuỗi đó hay không (và trả về một đối tượng khớp tương ứng nếu có, nhưng điều đó không quan trọng trong trường hợp này vì chúng tôi chỉ quan tâm xem kết quả có đúng hay không)
sepp2k

167

Ví dụ đầy đủ (Python 3):
Đối với Python 2.x, hãy xem Ghi chú bên dưới

import re

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

Bản in:

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

Ghi chú:

Đối với các nhà phát triển Python 2.x, filtertrả về một danh sách đã có. Trong Python, 3.xfilter đã được thay đổi để trả về một trình lặp, vì vậy nó phải được chuyển đổi thành list(để xem nó được in ra đẹp mắt).

Ví dụ về mã Python 3 Ví dụ về mã
Python 2.x


4
Xin chào, Khi tôi chạy đoạn mã trên, tôi nhận được <filter object at 0x1057acda0>Tôi đang làm gì sai?

1
Theo tài liệu python (python 2.7.12): docs.python.org/2/library/functions.html#filter bộ lọc trả về một danh sách không phải là một đối tượng. Bạn cũng có thể kiểm tra mã đó: repl.it/X3G/5786 (chỉ cần nhấn chạy)
Mercury

1
Cảm ơn bạn. Tôi đang sử dụng Python 3.5.2 trên máy Mac. Tôi đã thử liên kết của bạn. Tất nhiên nó hoạt động, mặc dù không chắc tại sao tôi nhận được tin nhắn đó. Tôi thậm chí loại bỏ các strtừ filterlợi nhuận một danh sách dù sao, không có kết quả ...

4
@joshua bạn đã có thể hình dung điều này bằng cách bây giờ nhưng thử print(list(newlist))hayprint([i for i in newlist])
James Draper

1
Điều này thật là khó. Đây là lý do tại sao R vượt trội hơn. Simply grep (pattern, vector_of_names)
MadmanLee

1

Để làm như vậy mà không cần biên dịch Regex trước, hãy sử dụng một lambdahàm - ví dụ:

from re import match

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

print(filtered_values)

Lợi nhuận:

['123', '234']

filter()chỉ lấy một callablelà đối số đầu tiên và trả về một danh sách trong đó có thể gọi đó trả về giá trị 'true'.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.