Saya tahu cara menggunakan keduanya untuk loop dan jika pernyataan pada baris terpisah, seperti:
>>> a = [2,3,4,5,6,7,8,9,0]
... xyz = [0,12,4,6,242,7,9]
... for x in xyz:
... if x in a:
... print(x)
0,4,6,7,9
Dan saya tahu saya bisa menggunakan daftar pemahaman untuk menggabungkan ini ketika pernyataan sederhana, seperti:
print([x for x in xyz if x in a])
Tetapi apa yang saya tidak dapat temukan adalah contoh yang baik di mana saja (untuk menyalin dan belajar dari) menunjukkan serangkaian perintah yang kompleks (bukan hanya "cetak x") yang terjadi setelah kombinasi dari loop for dan beberapa pernyataan if. Sesuatu yang saya harapkan terlihat seperti:
for x in xyz if x not in a:
print(x...)
Apakah ini bukan cara python seharusnya bekerja?
python
loops
if-statement
for-loop
ChewyChunks
sumber
sumber
for
perulangan danif
pernyataan eksplisit .x in a
lambat jikaa
daftar.Jawaban:
Anda dapat menggunakan ekspresi generator seperti ini:
sumber
gen = (y for (x,y) in enumerate(xyz) if x not in a)
mengembalikan >>>12
saat saya mengetikfor x in gen: print x
- jadi mengapa perilaku tak terduga dengan penghitungan?for x in xyz if x:
for x in (x for x in xyz if x not in a):
bekerja untuk saya, tetapi mengapa Anda seharusnya tidak hanya bisa melakukanfor x in xyz if x not in a:
, saya tidak yakin ...Per The Zen of Python (jika Anda bertanya-tanya apakah kode Anda adalah "Pythonic", itu adalah tempat untuk pergi):
Cara Pythonic untuk mendapatkan keduanya adalah:
sorted
intersection
set
Atau elemen-elemen yang ada
xyz
tetapi tidak dia
:Tetapi untuk loop yang lebih rumit, Anda mungkin ingin meratakannya dengan mengulangi ekspresi generator yang disebut dan / atau memanggil ke fungsi yang telah ditentukan. Mencoba menyesuaikan segala sesuatunya dalam satu baris jarang "Pythonic".
Perbarui komentar tambahan berikut pada pertanyaan Anda dan jawaban yang diterima
Saya tidak yakin apa yang ingin Anda lakukan
enumerate
, tetapi jikaa
ini adalah kamus, Anda mungkin ingin menggunakan kunci, seperti ini:sumber
Saya pribadi berpikir ini adalah versi tercantik:
Edit
jika Anda sangat ingin menghindari penggunaan lambda, Anda dapat menggunakan aplikasi fungsi parsial dan menggunakan modul operator (yang menyediakan fungsi sebagian besar operator).
https://docs.python.org/2/library/operator.html#module-operator
sumber
filter(a.__contains__, xyz)
. Biasanya ketika orang menggunakan lambda, mereka benar-benar membutuhkan sesuatu yang lebih sederhana.__contains__
adalah metode seperti yang lainnya, hanya metode khusus , artinya dapat dipanggil secara tidak langsung oleh operator (in
dalam hal ini). Tapi itu juga bisa disebut langsung, itu adalah bagian dari API publik. Nama-nama pribadi secara khusus didefinisikan memiliki paling banyak satu garis bawah garis, untuk memberikan pengecualian untuk nama metode khusus - dan mereka tunduk pada nama mangling ketika secara leksikal berada dalam cakupan kelas. Lihat docs.python.org/3/reference/datamodel.html#specialnames dan docs.python.org/3.6/tutorial/classes.html#private-variables .in
secara terpisah dikirimkan operan yang tepat). Selain itu, perhatikan bahwaoperator
juga mengeksporcontains
metode dengan nama__contains__
, jadi itu pasti bukan nama pribadi. Saya pikir Anda hanya harus belajar untuk hidup dengan fakta bahwa tidak setiap garis bawah ganda berarti "menjauh". : -]lambda
perlu memperbaiki untuk memasukkannot
:lambda w: not w in a, xyz
Berikut ini adalah penyederhanaan / satu kalimat dari jawaban yang diterima:
Perhatikan bahwa
generator
itu tetap sejajar . Ini diuji padapython2.7
danpython3.6
(perhatikan parens diprint
;))sumber
Saya mungkin akan menggunakan:
sumber
pythonic
hasil. Saya dapat kode secara fungsional dalam setiap bahasa lain yang saya gunakan (scala, kotlin, javascript, R, swift, ..) tetapi sulit / canggung dengan pythonsumber
import time a = [2,3,4,5,6,7,8,9,0] xyz = [0,12,4,6,242,7,9] start = time.time() print (set(a) & set(xyz)) print time.time() - start
if x in ignore: ...
.if set(a) - set(ignore) == set([]):
jadi mungkin itu sebabnya itu jauh lebih lambat daripada memeriksa keanggotaan. Saya akan menguji ini lagi di masa depan pada contoh yang jauh lebih sederhana daripada apa yang saya tulis.Anda dapat menggunakan generator juga, jika ekspresi generator menjadi terlalu terlibat atau kompleks:
sumber
Gunakan
intersection
atauintersection_update
persimpangan :
intersection_update :
maka
b
jawaban Anda adalahsumber
Saya menyukai jawaban Alex , karena filter adalah persis jika diterapkan ke daftar, jadi jika Anda ingin menjelajahi subset daftar yang diberikan syarat, ini sepertinya cara yang paling alami
metode ini berguna untuk pemisahan masalah, jika fungsi kondisinya berubah, satu-satunya kode yang digunakan adalah fungsi itu sendiri
The Generator Metode tampaknya lebih baik bila Anda tidak ingin anggota daftar, tapi modifikasi dari anggota mengatakan, yang tampaknya lebih cocok untuk sebuah pembangkit
Juga, filter bekerja dengan generator, meskipun dalam kasus ini tidak efisien
Tapi tentu saja, tetap menyenangkan menulis seperti ini:
sumber
Cara sederhana untuk menemukan elemen umum yang unik dari daftar a dan b:
sumber