Pemahaman daftar satu baris: varian if-else

178

Ini lebih lanjut tentang sintaksis pemahaman daftar python. Saya memiliki pemahaman daftar yang menghasilkan daftar angka ganjil dari rentang tertentu:

[x for x in range(1, 10) if x % 2]

Ini membuat filter - Saya punya daftar sumber, tempat saya menghapus angka genap ( if x % 2). Saya ingin menggunakan sesuatu seperti if-then-else di sini. Kode berikut gagal:

>>> [x for x in range(1, 10) if x % 2 else x * 100]
  File "<stdin>", line 1
    [x for x in range(1, 10) if x % 2 else x * 100]
                                         ^
SyntaxError: invalid syntax

Ada ekspresi python seperti if-else:

1 if 0 is 0 else 3

Bagaimana cara menggunakannya dalam pemahaman daftar?

Ducin
sumber
1
Fow apa nilainya, Anda memiliki "daftar pemahaman", bukan generator. Sintaks utamanya adalah sama kecuali bahwa generator menggunakan ()bukan [].
mgilson
2
Butuh waktu beberapa saat untuk mendapatkan mengapa if x % 2 eliminasi bahkan nomor (bukan menjaga mereka) - hal ini karena ketika xbahkan yang x % 2hasil ekspresi 0, yang, pada gilirannya, mengevaluasi ke False, sementara setiap intkecuali 0mengevaluasi ke True.

Jawaban:

328

x if y else zadalah sintaks untuk ekspresi yang Anda kembalikan untuk setiap elemen. Maka Anda membutuhkan:

[ x if x%2 else x*100 for x in range(1, 10) ]

Kebingungan muncul dari fakta Anda menggunakan filter pada contoh pertama, tetapi tidak pada yang kedua. Dalam contoh kedua Anda hanya memetakan setiap nilai ke yang lain, menggunakan ekspresi operator ternary.

Dengan filter, Anda perlu:

[ EXP for x in seq if COND ]

Tanpa filter Anda perlu:

[ EXP for x in seq ]

dan dalam contoh kedua Anda, ekspresi itu "kompleks", yang kebetulan melibatkan sebuah if-else.

shx2
sumber
2
Saya punya satu pertanyaan ... [x for x in range(1, 10) if x % 2]adalah sintaks yang benar. [x if x % 2 for x in range(1, 10)]- ini bukan, tapi [x if x%2 else x*100 for x in range(1, 10)]sekali lagi, sintaks yang benar. Bagaimana bisa?
ducin
@tkoomzaaskz dalam contoh kedua Anda, ini bukan operator ternary-if-else (hilang else), atau filter (karena itu pada EXPbagian dari pemahaman daftar)
shx2
3
@tkoomzaaskz Untuk lebih memperjelas, perhatikan bahwa Anda dapat menambahkan satu detik ifdi akhir: [x if x%2 else x*100 for x in range(1, 10) if not x%3]Yang pertama ifadalah bagian dari operator ternary, yang kedua ifadalah bagian dari sintaksis pemahaman daftar. Seluruhnya x if x%2 else x*100"pada tingkat yang sama" sebagai sederhana 2*x, itu ekspresi untuk mengevaluasi di sisi kiri for, ketika penyaringan if not x%3sudah terjadi.
zx81
Halo, akankah pernyataan satu baris lebih performan daripada membuatnya pada dua baris seperti for i in x:dan kemudian dalam for loop if i == y:?
Alexis. Rosland
23
[x if x % 2 else x * 100 for x in range(1, 10) ]
lucasg
sumber
12

Anda dapat melakukannya dengan pemahaman daftar juga:

A=[[x*100, x][x % 2 != 0] for x in range(1,11)]
print A
Stefan Gruenwald
sumber
1
Sangat bagus. Sepotong boolean. Terima kasih Anda baru saja memberi saya solusi yang lebih mudah dibaca.
Anda juga dapat melipatgandakan penetapan seperti: A, B = [10,11] [a == 19], [1,14] [a == 20]
Stefan Gruenwald
10

Hanya solusi lain, semoga seseorang menyukainya:

Menggunakan: [Salah, Benar] [Ekspresi]

>>> map(lambda x: [x*100, x][x % 2 != 0], range(1,10))
[1, 200, 3, 400, 5, 600, 7, 800, 9]
>>>
James Sapam
sumber
3

Saya bisa melakukan ini

>>> [x if x % 2 != 0 else x * 100 for x in range(1,10)]
    [1, 200, 3, 400, 5, 600, 7, 800, 9]
>>>
anudeep
sumber