Pikirkan tentang fungsi yang saya panggil untuk efek sampingnya, bukan nilai yang dikembalikan (seperti mencetak ke layar, memperbarui GUI, mencetak ke file, dll.).
def fun_with_side_effects(x):
...side effects...
return y
Sekarang, apakah Pythonic menggunakan pemahaman daftar untuk memanggil fungsi ini:
[fun_with_side_effects(x) for x in y if (...conditions...)]
Perhatikan bahwa saya tidak menyimpan daftar di mana pun
Atau haruskah saya menyebut fungsi ini seperti ini:
for x in y:
if (...conditions...):
fun_with_side_effects(x)
Mana yang lebih baik dan mengapa?
python
list-comprehension
sinan
sumber
sumber
for ... in
digunakan dalam kedua kasus - mengarah ke pertanyaan seperti ini!Jawaban:
Sangat anti-Pythonic untuk melakukannya, dan Pythonista berpengalaman apa pun akan membuat Anda kesal. Daftar perantara dibuang setelah dibuat, dan berpotensi menjadi sangat, sangat besar, dan karena itu mahal untuk dibuat.
sumber
for
sebelumnya, untuk menyingkirkanif
).Anda tidak boleh menggunakan pemahaman daftar , karena seperti yang dikatakan orang-orang itu akan membangun daftar sementara yang besar yang tidak Anda perlukan. Dua metode berikut ini setara:
dengan definisi
consume
dariitertools
halaman manual:Tentu saja, yang terakhir lebih jelas dan lebih mudah dimengerti.
sumber
map
mungkin tidak seintuitif jika seseorang belum pernah melakukan pemrograman fungsional sebelumnya.consume = collections.deque(maxlen=0).extend
Pemahaman daftar adalah untuk membuat daftar. Dan kecuali Anda benar-benar membuat daftar, Anda tidak boleh menggunakan pemahaman daftar.
Jadi saya akan mendapatkan opsi kedua, hanya mengulang-ulang daftar dan kemudian memanggil fungsi ketika kondisi berlaku.
sumber
Kedua lebih baik.
Pikirkan orang yang perlu memahami kode Anda. Anda bisa mendapatkan karma buruk dengan mudah dengan yang pertama :)
Anda bisa pergi ke tengah di antara keduanya dengan menggunakan filter (). Perhatikan contohnya:
sumber
lambda x : x > 3
.for el in (x for x in y if x > 3):
.el
danx
bisa memiliki nama yang sama, tapi itu mungkin membingungkan orang.Tergantung pada tujuan Anda.
Jika Anda mencoba melakukan beberapa operasi pada setiap objek dalam daftar, pendekatan kedua harus diterapkan.
Jika Anda mencoba membuat daftar dari daftar lain, Anda dapat menggunakan pemahaman daftar.
sumber
Anda dapat melakukan
tapi itu tidak terlalu cantik.
sumber
Menggunakan pemahaman daftar untuk efek sampingnya jelek, non-Pythonic, tidak efisien, dan saya tidak akan melakukannya. Saya akan menggunakan
for
loop sebagai gantinya, karenafor
loop menandakan gaya prosedural di mana efek samping itu penting.Tapi, jika Anda benar-benar bersikeras menggunakan pemahaman daftar untuk efek sampingnya, Anda harus menghindari inefisiensi dengan menggunakan ekspresi generator sebagai gantinya. Jika Anda benar-benar bersikeras pada gaya ini, lakukan salah satu dari dua berikut ini:
atau:
Ini adalah ekspresi generator, dan mereka tidak menghasilkan daftar acak yang dibuang. saya pikir
all
bentuknya mungkin sedikit lebih jelas, meskipun menurut saya keduanya membingungkan dan tidak boleh digunakan.Saya pikir ini jelek dan saya tidak akan benar-benar melakukannya dalam kode. Tetapi jika Anda bersikeras menerapkan loop Anda dengan cara ini, begitulah cara saya melakukannya.
Saya cenderung merasa bahwa pemahaman daftar dan sejenisnya harus menandakan upaya untuk menggunakan sesuatu yang setidaknya mirip dengan gaya fungsional. Menempatkan hal-hal dengan efek samping yang merusak asumsi itu akan menyebabkan orang harus membaca kode Anda lebih hati-hati, dan saya pikir itu hal yang buruk.
sumber
fun_with_side_effects
mengembalikan True?itertools.consume
tidak ada lagi, mungkin karena menggunakan pemahaman dengan efek samping jelek.