Saya memiliki beberapa daftar yang memiliki jumlah entri yang sama (masing-masing menentukan properti objek):
property_a = [545., 656., 5.4, 33.]
property_b = [ 1.2, 1.3, 2.3, 0.3]
...
dan daftar dengan bendera dengan panjang yang sama
good_objects = [True, False, False, True]
(yang dapat dengan mudah diganti dengan daftar indeks yang setara:
good_indices = [0, 3]
Apa cara termudah untuk menghasilkan daftar baru property_asel
, property_bsel
, ... yang hanya berisi nilai-nilai yang ditunjukkan baik oleh True
entri atau indeks?
property_asel = [545., 33.]
property_bsel = [ 1.2, 0.3]
zip
di Python 2 akan membuat daftar baru, tetapi di Python 3 itu hanya akan mengembalikan generator (malas).from itertools import izip
dan menggunakannya sebagai gantizip
contoh pertama. Itu menciptakan sebuah iterator, sama seperti Python 3.Saya melihat 2 opsi.
Menggunakan numpy:
property_a = numpy.array([545., 656., 5.4, 33.]) property_b = numpy.array([ 1.2, 1.3, 2.3, 0.3]) good_objects = [True, False, False, True] good_indices = [0, 3] property_asel = property_a[good_objects] property_bsel = property_b[good_indices]
Menggunakan pemahaman daftar dan zip itu:
property_a = [545., 656., 5.4, 33.] property_b = [ 1.2, 1.3, 2.3, 0.3] good_objects = [True, False, False, True] good_indices = [0, 3] property_asel = [x for x, y in zip(property_a, good_objects) if y] property_bsel = [property_b[i] for i in good_indices]
sumber
[property_b[i] for i in good_indices]
bagus untuk digunakan tanpanumpy
Gunakan zip fungsi bawaan
property_asel = [a for (a, truth) in zip(property_a, good_objects) if truth]
EDIT
Hanya melihat fitur baru 2.7. Sekarang ada fungsi dalam modul itertools yang mirip dengan kode di atas.
http://docs.python.org/library/itertools.html#itertools.compress
itertools.compress('ABCDEF', [1,0,1,0,1,1]) => A, C, E, F
sumber
itertools.compress
sini. Pemahaman daftar jauh lebih mudah dibaca, tanpa harus menggali apa yang dilakukan kompres.itertools.compress
alih - alih menyalin menempel contoh dokumentasi?Dengan asumsi Anda hanya memiliki daftar item dan daftar indeks benar / diperlukan, ini harus menjadi yang tercepat:
property_asel = [ property_a[index] for index in good_indices ]
Ini berarti pemilihan properti hanya akan melakukan putaran sebanyak ada indeks yang benar / diperlukan. Jika Anda memiliki banyak daftar properti yang mengikuti aturan daftar tag tunggal (benar / salah), Anda dapat membuat daftar indeks menggunakan prinsip pemahaman daftar yang sama:
good_indices = [ index for index, item in enumerate(good_objects) if item ]
Ini mengulangi setiap item dalam good_objects (sambil mengingat indeksnya dengan enumerate) dan hanya mengembalikan indeks di mana item tersebut benar.
Bagi siapa pun yang tidak memahami daftar, berikut adalah versi prosa bahasa Inggris dengan kode yang disorot dalam huruf tebal:
daftar indeks untuk setiap kelompok indeks, barang yang ada di sebuah enumerasi dari benda-benda yang baik , jika (di mana) yang item yang Benar
sumber
Bahasa Matlab dan Scilab menawarkan sintaks yang lebih sederhana dan lebih elegan daripada Python untuk pertanyaan yang Anda ajukan, jadi menurut saya yang terbaik yang dapat Anda lakukan adalah meniru Matlab / Scilab dengan menggunakan paket Numpy dengan Python. Dengan melakukan ini, solusi untuk masalah Anda sangat ringkas dan elegan:
from numpy import * property_a = array([545., 656., 5.4, 33.]) property_b = array([ 1.2, 1.3, 2.3, 0.3]) good_objects = [True, False, False, True] good_indices = [0, 3] property_asel = property_a[good_objects] property_bsel = property_b[good_indices]
Numpy mencoba meniru Matlab / Scilab tetapi ada biayanya: Anda perlu mendeklarasikan setiap daftar dengan kata kunci "array", sesuatu yang akan membebani skrip Anda (masalah ini tidak ada pada Matlab / Scilab). Perhatikan bahwa solusi ini terbatas pada larik angka, yang merupakan kasus dalam contoh Anda.
sumber
filter
atau pustaka eksternalpandas
. Jika Anda akan menukar bahasa, Anda juga dapat mencoba R, tetapi bukan itu pertanyaannya .