Ekspresi Reguler: Cari dalam daftar

91

Saya ingin memfilter string dalam daftar berdasarkan ekspresi reguler.

Apakah ada yang lebih baik dari [x for x in list if r.match(x)]?

leoluk
sumber

Jawaban:

116

Anda dapat membuat iterator dengan Python 3.x atau daftar dengan Python 2.x dengan menggunakan:

filter(r.match, list)

Untuk mengubah iterator Python 3.x menjadi sebuah daftar, cukup lakukan; list(filter(..)).

sepp2k.dll
sumber
2
Sebenarnya, pemahaman daftar biasanya lebih disukai daripada konstruksi fungsional seperti filter, reduce, lambda, dll.
Ivo van der Wijk
39
@Ivo: Mereka biasanya disukai karena biasanya lebih jelas dan lebih ringkas. Namun dalam kasus ini, filterversinya sangat jelas dan memiliki noise yang jauh lebih sedikit.
sepp2k
9
ada apa r.matchdisini?
rbatt
2
@rbatt r.matchadalah metode yang, ketika diterapkan ke string tertentu, menemukan apakah regex rcocok dengan string itu (dan mengembalikan objek pencocokan jika demikian, tetapi itu tidak masalah dalam kasus ini karena kami hanya peduli apakah hasilnya benar)
sepp2k
174

Contoh Lengkap (Python 3):
Untuk Python 2.x lihat Catatan di bawah ini

import re

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

Cetakan:

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

catatan:

Untuk pengembang Python 2.x, sudah filtermengembalikan daftar. Dalam Python 3.xfilter diubah untuk mengembalikan iterator sehingga harus diubah menjadi list(untuk melihatnya dicetak dengan baik).

Contoh kode Python 3 Contoh kode
Python 2.x.

Air raksa
sumber
4
Halo, Ketika saya menjalankan kode di atas, saya mengerti <filter object at 0x1057acda0>Apa yang saya lakukan salah?
1
Menurut dokumen python (python 2.7.12): docs.python.org/2/library/functions.html#filter filter mengembalikan daftar bukan objek. Anda juga dapat memeriksa kode itu: repl.it/X3G/5786 (tekan saja)
Mercury
1
Terima kasih. Saya menggunakan Python 3.5.2 di Mac. Saya mencoba tautan Anda. Tentu saja berhasil, meskipun tidak yakin mengapa saya mendapatkan pesan itu. Saya bahkan menghapus strsejak filtermengembalikan daftar, tidak berhasil ...
4
@ Joshua Anda mungkin sudah mengetahui hal ini sekarang, tetapi coba print(list(newlist))atauprint([i for i in newlist])
James Draper
1
Ini sangat sulit. Inilah mengapa R lebih unggul. Cukup grep (pola, vector_of_names)
MadmanLee
1

Untuk melakukannya tanpa mengompilasi Regex terlebih dahulu, gunakan lambdafungsi - misalnya:

from re import match

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

print(filtered_values)

Pengembalian:

['123', '234']

filter()hanya mengambil callablesebagai argumen pertamanya, dan mengembalikan daftar di mana callable itu mengembalikan nilai 'kebenaran'.

Collin Heist
sumber