Mengapa daftar tidak memiliki metode "get" aman seperti kamus?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
Mengapa daftar tidak memiliki metode "get" aman seperti kamus?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
l[10:11]
alih-alihl[10]
, misalnya. () Sublist Th akan memiliki elemen yang diinginkan jika ada).get
. Itu akan menjadi setara denganl[i] if i < len(l) else default
, tetapi lebih mudah dibaca, lebih ringkas, dan memungkinkan untuki
menjadi ekspresi tanpa harus menghitung ulangNone
jika tidak ada. Akan lebih baik untuk mengatakannyax = expensive().get(0, None)
sehingga saya tidak perlu memasukkan pengembalian mahal yang tidak berguna ke dalam variabel sementara.Jawaban:
Pada akhirnya itu mungkin tidak memiliki
.get
metode yang aman karena adict
adalah kumpulan asosiatif (nilai dikaitkan dengan nama) di mana tidak efisien untuk memeriksa apakah kunci ada (dan mengembalikan nilainya) tanpa melemparkan pengecualian, sementara itu super sepele untuk menghindari pengecualian mengakses elemen daftar (karenalen
metode ini sangat cepat). The.get
Metode memungkinkan Anda untuk query nilai yang terkait dengan nama, tidak langsung mengakses item ke-37 dalam kamus (yang akan lebih seperti apa yang Anda minta dari daftar Anda).Tentu saja, Anda dapat dengan mudah menerapkan ini sendiri:
Anda bahkan dapat melakukan monkeypatch ke
__builtins__.list
konstruktor di__main__
, tetapi itu akan menjadi perubahan yang tidak terlalu luas karena sebagian besar kode tidak menggunakannya. Jika Anda hanya ingin menggunakan ini dengan daftar yang dibuat oleh kode Anda sendiri, Anda dapat dengan mudah membuat subkelaslist
dan menambahkanget
metode.sumber
list
.get
memecahkan masalah yang tidak dimiliki daftar - cara efisien untuk menghindari pengecualian saat mendapatkan data yang mungkin tidak ada. Sangat sepele dan sangat efisien untuk mengetahui apa itu indeks daftar yang valid, tetapi tidak ada cara yang sangat baik untuk melakukan ini untuk nilai-nilai kunci dalam kamus.O(1)
. Ini tidak akan cukup cepat dalam hal mentah seperti memeriksalen
, tetapi dari sudut pandang kompleksitas mereka semuaO(1)
. Jawaban yang benar adalah penggunaan / semantik yang khas ...dict
hanya yang terbaik O (1), tidak semua kasus..get()
atau Anda memiliki masalah di tempat lain dalam kode Anda (atau lingkungan). Titik menggunakan metode seperti itu adalah keterbacaan kode. Teknik "vanilla" membutuhkan empat baris kode di setiap tempat yang perlu dilakukan. The.get()
teknik hanya membutuhkan satu dan dapat dengan mudah dirantai dengan metode panggilan berikutnya (misalnyamy_list.get(2, '').uppercase()
).Ini berfungsi jika Anda ingin elemen pertama, seperti
my_list.get(0)
Saya tahu itu bukan apa yang Anda minta, tetapi mungkin bisa membantu orang lain.
sumber
next(iter(my_list[index:index+1]), 'fail')
Memungkinkan untuk indeks apapun, bukan hanya 0 Atau kurang FP tapi bisa dibilang lebih Pythonic, dan hampir pasti lebih mudah dibaca:my_list[index] if index < len(my_list) else 'fail'
.Mungkin karena itu tidak masuk akal untuk daftar semantik. Namun, Anda dapat dengan mudah membuatnya sendiri dengan mensubclassing.
sumber
get
metode yang bagus . Jumlah keterbacaan diperhitungkan. Dan keterbacaan menderita dengan setiap kelas tambahan yang tidak perlu. Cukup gunakantry / except
pendekatan tanpa membuat subclass.Alih-alih menggunakan .get, menggunakan seperti ini seharusnya ok untuk daftar. Hanya perbedaan penggunaan.
sumber
.get
metode (kecuali saya tidak yakin bagaimana Anda akan menjelaskan apa arti indeks dalam kasus ini, atau mengapa itu akan gagal).lst[i] if -len(lst) <= i < len(l) else 'fail'
Coba ini:
sumber
Penghargaan untuk jose.angel.jimenez
Untuk penggemar "oneliner" ...
Jika Anda ingin elemen pertama daftar atau jika Anda ingin nilai default jika daftar kosong coba:
kembali
a
dan
kembali
default
Contoh untuk elemen lain ...
Dengan fallback default ...
Diuji dengan
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
sumber
value, = liste[:1] or ('default',)
. Sepertinya Anda membutuhkan tanda kurung.Hal terbaik yang dapat Anda lakukan adalah mengubah daftar menjadi dict dan kemudian mengaksesnya dengan metode get:
sumber
zip range len
hal itu, orang hanya bisa menggunakandict(enumerate(my_list))
Jadi saya melakukan penelitian lebih lanjut tentang ini dan ternyata tidak ada yang spesifik untuk ini. Saya merasa senang ketika saya menemukan list.index (nilai), itu mengembalikan indeks dari item yang ditentukan, tetapi tidak ada apa pun untuk mendapatkan nilai pada indeks tertentu. Jadi jika Anda tidak ingin menggunakan solusi safe_list_get yang menurut saya cukup bagus. Berikut adalah beberapa kalimat jika pernyataan yang dapat menyelesaikan pekerjaan untuk Anda tergantung pada skenario:
Anda juga dapat menggunakan Tidak Ada alih-alih 'Tidak', yang lebih masuk akal .:
Juga jika Anda ingin mendapatkan item pertama atau terakhir dalam daftar, ini berfungsi
Anda juga dapat menjadikan ini fungsi tetapi saya masih menyukai solusi pengecualian IndexError. Saya bereksperimen dengan versi
safe_list_get
solusi bodoh dan membuatnya sedikit lebih sederhana (tidak ada default):Belum diperbandingkan untuk melihat apa yang tercepat.
sumber
list
dengan mensubklasifikasikannya. Dengan cara itu konstruktor dapat mengambillist
atau apa pun yang berperilaku seperti daftar, dan contoh baru berperilaku sepertilist
. Lihat jawaban Keith di bawah ini yang seharusnya menjadi yang diterima IMHO.dict.get()
mengembalikan nilai default dari referensi indeks daftar daripada harus menangkapIndexError
? Jadi ini benar-benar tentang fitur bahasa / perpustakaan (dan bukan OOP vs. konteks FP) .Selain itu, seseorang mungkin harus memenuhi syarat penggunaan 'pythonic' Anda sebagai WWGD (karena penghinaannya terhadap FP Python sudah dikenal) dan tidak harus memuaskan PEP8 / 20 saja.el = x[4] if len(x) == 4 else 'No'
- maksud Andalen(x) > 4
?x[4]
di luar batas jikalen(x) == 4
.Kamus untuk mencari. Masuk akal untuk bertanya apakah ada entri atau tidak. Daftar biasanya diulang. Tidak umum untuk bertanya apakah L [10] ada tetapi jika panjang L adalah 11.
sumber
Usecase Anda pada dasarnya hanya relevan ketika melakukan array dan matriks dengan panjang tetap, sehingga Anda tahu berapa lama mereka berada di depan. Dalam hal ini Anda biasanya juga membuat mereka sebelum mengisi mereka dengan None atau 0, sehingga sebenarnya setiap indeks yang akan Anda gunakan sudah ada.
Anda bisa mengatakan ini: Saya perlu .get () kamus cukup sering. Setelah sepuluh tahun sebagai programmer penuh waktu, saya rasa saya tidak pernah membutuhkannya dalam daftar. :)
sumber
'lalala' in url.split('/')[2:]
. Tetapi masalah dengan solusi Anda di sini adalah bahwa Anda hanya melihat elemen kedua. Bagaimana jika URLnya adalah '/ monkeybonkey / lalala'? Anda akan mendapatkanTrue
meskipun URL tidak valid.