Saya memiliki daftar nilai yang perlu saya filter mengingat nilai dalam daftar boolean:
list_a = [1, 2, 4, 6]
filter = [True, False, True, False]
Saya membuat daftar yang difilter baru dengan baris berikut:
filtered_list = [i for indx,i in enumerate(list_a) if filter[indx] == True]
yang mengakibatkan:
print filtered_list
[1,4]
Garis bekerja tetapi terlihat (bagi saya) sedikit berlebihan dan saya bertanya-tanya apakah ada cara yang lebih sederhana untuk mencapai hal yang sama.
Saran
Ringkasan dua nasihat baik yang diberikan dalam jawaban di bawah ini:
1- Jangan beri nama daftar filter
seperti yang saya lakukan karena ini adalah fungsi bawaan.
2- Jangan membandingkan hal-hal True
seperti yang saya lakukan dengan if filter[idx]==True..
karena itu tidak perlu. Cukup menggunakan if filter[idx]
sudah cukup.
if filter[indx] == True
Do tidak menggunakan==
jika Anda ingin memeriksa identitas denganTrue
, penggunaanis
. Pokoknya dalam hal ini seluruh perbandingan tidak berguna, Anda bisa menggunakannyaif filter[indx]
. Terakhir: jangan pernah menggunakan nama built-in sebagai nama variabel / modul (saya mengacu pada namafilter
). Menggunakan sesuatu sepertiincluded
, sehinggaif
terbaca dengan baik (if included[indx]
).Jawaban:
Anda sedang mencari
itertools.compress
:Perbandingan waktu (py3.x):
Jangan gunakan
filter
sebagai nama variabel, itu adalah fungsi bawaan.sumber
[2, 6]
?list(compress(list_a, [not i for i in fill]))
harus kembali[2, 6]
Seperti itu:
Menggunakan
zip
adalah cara pythonic untuk beralih pada beberapa urutan secara paralel, tanpa perlu pengindeksan apa pun. Ini mengasumsikan kedua sekuens memiliki panjang yang sama (zip berhenti setelah kehabisan terpendek). Menggunakanitertools
untuk kasus sederhana semacam itu agak berlebihan ...Satu hal yang Anda lakukan dalam contoh Anda, yang benar-benar harus Anda hentikan adalah membandingkan berbagai hal dengan True, ini biasanya tidak perlu. Alih-alih
if filter[idx]==True: ...
, Anda cukup menulisif filter[idx]: ...
.sumber
Dengan numpy:
atau lihat jawaban Alex Szatmary jika list_a dapat berupa array numpy tetapi tidak filter
Numpy biasanya memberi Anda dorongan kecepatan besar juga
sumber
NumPy
lebih dari yanglist
mungkin. Tetapi jika Anda haruslist
tetap menggunakan , Anda memiliki (menggunakanNumPy
solusi) buatnp.array
dari kedua daftar, gunakan pengindeksan boolean dan akhirnya mengubah array kembali ke daftar dengantolist()
metode. Untuk lebih tepatnya, Anda harus memasukkan benda-benda itu ke dalam perbandingan waktu. Kemudian, menggunakanitertools.compress
akan tetap menjadi solusi tercepat.Untuk melakukan ini menggunakan numpy, yaitu, jika Anda memiliki array
a
,, bukannyalist_a
:sumber
where
.sumber
Dengan python 3 Anda bisa menggunakan
list_a[filter]
untuk mendapatkanTrue
nilai. Untuk mendapatkanFalse
nilai, gunakanlist_a[~filter]
sumber