Seperti yang kita semua tahu, ada pemahaman daftar, seperti
[i for i in [1, 2, 3, 4]]
dan ada pemahaman kamus, seperti
{i:j for i, j in {1: 'a', 2: 'b'}.items()}
tapi
(i for i in (1, 2, 3))
akan berakhir di generator, bukan tuple
pemahaman. Mengapa demikian?
Dugaan saya adalah bahwa a tuple
tidak berubah, tetapi ini sepertinya bukan jawabannya.
{i:j for i,j in {1:'a', 2:'b'}}
seharusnya{i:j for i,j in {1:'a', 2:'b'}.items()}
Jawaban:
Anda dapat menggunakan ekspresi generator:
tetapi tanda kurung sudah diambil untuk… ekspresi generator.
sumber
list(i for i in (1,2,3))
. Saya benar-benar berpikir itu hanya karena tidak ada sintaks yang bersih untuk itu (atau setidaknya tidak ada yang memikirkannya)list(i for i in (1, 2, 3))
adalah ekspresi generator yang menampilkan daftar,set(i for i in (1, 2, 3))
mengeluarkan satu set. Apakah itu berarti sintaks pemahaman tidak diperlukan? Mungkin tidak, tapi ini sangat berguna. Untuk kasus yang jarang Anda membutuhkan tuple sebagai gantinya, ekspresi generator akan melakukan, jelas, dan tidak memerlukan penemuan penjepit atau braket lain.[thing for thing in things]
membangun daftar lebih cepat daripadalist(thing for thing in things)
. Pemahaman tuple tidak akan sia-sia;tuple(thing for thing in things)
memiliki masalah latensi dantuple([thing for thing in things])
dapat memiliki masalah memori.A list or set or dict comprehension is just syntactic sugar to use a generator expression
? Ini menyebabkan kebingungan oleh orang-orang yang melihat ini sebagai cara yang setara untuk mencapai tujuan. Ini bukan gula sintaksis secara teknis karena prosesnya sebenarnya berbeda, bahkan jika produk akhirnya sama.Raymond Hettinger (salah satu pengembang inti Python) mengatakan ini tentang tuple dalam tweet baru - baru ini :
Ini (bagi saya) mendukung gagasan bahwa jika item-item dalam suatu urutan cukup terkait untuk dihasilkan oleh generator, well, maka itu haruslah sebuah daftar. Meskipun tuple dapat diubah dan sepertinya hanya daftar yang tidak dapat diubah, itu benar-benar setara dengan Python dari struct C:
menjadi dengan Python
sumber
operator.itemgetter
dalam kasus itu.tuple(obj[item] for item in items)
secara langsung. Dalam kasus saya, saya menanamkan ini ke dalam daftar pemahaman untuk membuat daftar rekaman tuple. Jika saya perlu melakukan ini berulang kali di seluruh kode maka itemgetter tampak hebat. Mungkin itemgetter akan lebih idiomatis?Karena Python 3.5 , Anda juga dapat menggunakan
*
sintaks percikan unpacking untuk membongkar ekspresi generator:sumber
tuple(list(x for x in range(10)))
( jalur kode identik , dengan keduanya membangun alist
, dengan satu-satunya perbedaan adalah bahwa langkah terakhir adalah membuattuple
darilist
dan membuanglist
saattuple
keluaran) diperlukan). Berarti Anda tidak benar-benar menghindari sepasang temporer.*(x for x in range(10))
tidak berhasil. Saya mengertiSyntaxError: can't use starred expression here
. Namuntuple(x for x in range(10))
berhasil.Seperti yang
macm
disebutkan poster lain , cara tercepat untuk membuat tuple dari generator adalahtuple([generator])
.Perbandingan Kinerja
Pemahaman daftar:
Tuple dari pemahaman daftar:
Tuple dari generator:
Tuple dari membongkar:
Versi python saya :
Jadi, Anda harus selalu membuat tuple dari daftar pemahaman kecuali kinerja tidak menjadi masalah.
sumber
tuple
dari listcomp membutuhkan penggunaan memori puncak berdasarkan ukuran gabungan dari finaltuple
danlist
.tuple
dari genexpr, sementara lebih lambat, berarti Anda hanya membayar untuk finaltuple
, tidak sementaralist
(genexpr itu sendiri menempati memori yang kurang lebih tetap). Biasanya tidak bermakna, tetapi bisa jadi penting ketika ukuran yang terlibat sangat besar.Pemahaman bekerja dengan mengulang atau mengulangi item dan menugaskannya ke dalam wadah, Tuple tidak dapat menerima tugas.
Setelah Tuple dibuat, itu tidak dapat ditambahkan ke, diperpanjang, atau ditugaskan. Satu-satunya cara untuk memodifikasi Tuple adalah jika salah satu objek itu sendiri dapat ditugaskan (adalah wadah non-tuple). Karena Tuple hanya memegang referensi ke objek semacam itu.
Juga - tuple memiliki konstruktor sendiri
tuple()
yang dapat Anda berikan iterator apa pun. Yang berarti bahwa untuk membuat tuple, Anda dapat melakukan:sumber
lst = [x for x in ...]; x.append()
?Dugaan terbaik saya adalah mereka kehabisan kurung dan tidak berpikir itu akan cukup berguna untuk warwar menambahkan sintaks "jelek" ...
sumber
{*()}
, meskipun jelek, berfungsi sebagai himpunan literal kosong!set()
:){*[]}
benar-benar kalah dengan opsi lain; string kosong dan kosongtuple
, tidak berubah, adalah lajang, sehingga tidak ada sementara diperlukan untuk membangun kosongset
. Sebaliknya, yang kosonglist
bukan singleton, jadi Anda benar-benar harus membangunnya, menggunakannya untuk membangunnyaset
, lalu menghancurkannya, kehilangan keuntungan kinerja sepele apa pun yang disediakan oleh operator monyet bermata satu.Tuples tidak dapat secara efisien ditambahkan seperti daftar.
Jadi pemahaman tuple perlu menggunakan daftar secara internal dan kemudian dikonversi menjadi tuple.
Itu akan sama dengan apa yang Anda lakukan sekarang: tuple ([pemahaman])
sumber
Kurung tidak membuat tupel. alias satu = (dua) bukan tupel. Satu-satunya jalan keluar adalah salah satu = (dua,) atau satu = tupel (dua). Jadi solusinya adalah:
sumber
Saya percaya itu hanya demi kejelasan, kami tidak ingin mengacaukan bahasa dengan terlalu banyak simbol yang berbeda. Juga
tuple
pemahaman tidak pernah diperlukan , daftar hanya dapat digunakan sebagai gantinya dengan perbedaan kecepatan yang dapat diabaikan, tidak seperti pemahaman dict yang bertentangan dengan pemahaman daftar.sumber
Kami dapat menghasilkan tupel dari pemahaman daftar. Yang berikut menambahkan dua angka secara berurutan ke dalam tuple dan memberikan daftar dari angka 0-9.
sumber