1) Gaya yang hampir berbahasa Inggris:
Tes keberadaan menggunakan in
operator, lalu terapkan remove
metode.
if thing in some_list: some_list.remove(thing)
The remove
Metode akan menghapus hanya kejadian pertama thing
, dalam rangka untuk menghapus semua kejadian yang dapat Anda gunakan while
bukan if
.
while thing in some_list: some_list.remove(thing)
- Cukup sederhana, mungkin pilihan saya. Untuk daftar kecil (tidak bisa menolak satu kalimat)
Sikap menembak-dulu-bertanya-terakhir-ini umum dalam Python. Alih-alih menguji terlebih dahulu jika objek tersebut cocok, lakukan saja operasi dan tangkap Pengecualian yang relevan:
try:
some_list.remove(thing)
except ValueError:
pass # or scream: thing not in some_list!
except AttributeError:
call_security("some_list not quacking like a list!")
Tentu saja yang kedua kecuali klausa dalam contoh di atas tidak hanya humor yang dipertanyakan tetapi sama sekali tidak perlu (intinya adalah untuk menggambarkan mengetik bebek untuk orang-orang yang tidak akrab dengan konsep).
Jika Anda mengharapkan beberapa kejadian:
while True:
try:
some_list.remove(thing)
except ValueError:
break
- sedikit verbose untuk kasus penggunaan khusus ini, tetapi sangat idiomatis dengan Python.
- ini berkinerja lebih baik daripada # 1
- PEP 463 mengusulkan sintaks yang lebih pendek untuk mencoba / kecuali penggunaan sederhana yang akan berguna di sini, tetapi itu tidak disetujui.
Namun, dengan penekan contextlib () contextmanager (diperkenalkan dengan python 3.4) kode di atas dapat disederhanakan menjadi:
with suppress(ValueError, AttributeError):
some_list.remove(thing)
Sekali lagi, jika Anda mengharapkan beberapa kejadian:
with suppress(ValueError):
while True:
some_list.remove(thing)
3) Gaya fungsional:
Sekitar tahun 1993, Python mendapat lambda
, reduce()
, filter()
dan map()
, courtesy of Lisp hacker yang merindukan mereka dan patch bekerja diserahkan *. Anda dapat menggunakan filter
untuk menghapus elemen dari daftar:
is_not_thing = lambda x: x is not thing
cleaned_list = filter(is_not_thing, some_list)
Ada jalan pintas yang mungkin berguna untuk kasus Anda: jika Anda ingin menyaring item kosong (pada kenyataannya item di mana bool(item) == False
, seperti None
, nol, string kosong atau koleksi kosong lainnya), Anda dapat melewati Tidak ada sebagai argumen pertama:
cleaned_list = filter(None, some_list)
- [pembaruan] : dengan Python 2.x,
filter(function, iterable)
digunakan untuk menjadi setara dengan [item for item in iterable if function(item)]
(atau [item for item in iterable if item]
jika argumen pertama adalah None
); di Python 3.x, sekarang setara dengan (item for item in iterable if function(item))
. Perbedaannya adalah filter yang digunakan untuk mengembalikan daftar, sekarang berfungsi seperti ekspresi generator - ini OK jika Anda hanya mengulangi daftar yang sudah dibersihkan dan membuangnya, tetapi jika Anda benar-benar membutuhkan daftar, Anda harus menyertakan filter()
panggilan dengan list()
konstruktor.
- * Konstruksi rasa Lispy ini dianggap sedikit asing dengan Python. Sekitar tahun 2005, Guido bahkan berbicara tentang menjatuhkan
filter
- bersama dengan teman map
dan reduce
(mereka belum pergi tetapi reduce
dipindahkan ke modul functools , yang layak dilihat jika Anda menyukai fungsi pesanan tinggi ).
4) Gaya matematika:
Pemahaman daftar menjadi gaya yang disukai untuk manipulasi daftar dengan Python sejak diperkenalkan pada versi 2.0 oleh PEP 202 . Alasan di balik itu adalah bahwa Daftar comprehensions menyediakan cara yang lebih ringkas untuk membuat daftar dalam situasi di mana map()
dan filter()
dan / atau loop bersarang saat ini akan digunakan.
cleaned_list = [ x for x in some_list if x is not thing ]
Ekspresi generator diperkenalkan dalam versi 2.4 oleh PEP 289 . Ekspresi generator lebih baik untuk situasi di mana Anda tidak benar-benar perlu (atau ingin) membuat daftar lengkap dalam memori - seperti ketika Anda hanya ingin mengulangi elemen satu per satu. Jika Anda hanya mengulangi daftar, Anda dapat menganggap ekspresi generator sebagai pemahaman daftar yang dievaluasi malas :
for item in (x for x in some_list if x is not thing):
do_your_thing_with(item)
Catatan
- Anda mungkin ingin menggunakan operator ketimpangan
!=
alih-alih is not
( perbedaannya penting )
- untuk kritik terhadap metode yang menyiratkan salinan daftar: bertentangan dengan kepercayaan populer, ekspresi generator tidak selalu lebih efisien daripada pemahaman daftar - silakan profil sebelum mengeluh
Perhatikan bahwa ini hanya akan menghapus satu instance dari string kosong dari daftar Anda (seperti kode Anda juga akan). Bisakah daftar Anda memuat lebih dari satu?
sumber
Jika
index
tidak menemukan string yang dicari, itu melempar yangValueError
Anda lihat. Entah menangkap ValueError:atau gunakan
find
, yang mengembalikan -1 dalam kasus itu.sumber
>>> s [u'Hello', u'Cool', u'Glam'] >>> i = s.find("") Traceback (most recent call last): File "<pyshell#42>", line 1, in <module> i = s.find("") AttributeError: 'list' object has no attribute 'find'
remove()
jauh lebih langsung: itu secara langsung menunjukkan apa yang harus dilakukan oleh kode (memang tidak perlu indeks perantarai
).Menambahkan jawaban ini untuk kelengkapan, meskipun hanya dapat digunakan dalam kondisi tertentu.
Jika Anda memiliki daftar yang sangat besar, menghapus dari akhir daftar menghindari keharusan internal CPython
memmove
, untuk situasi di mana Anda dapat memesan ulang daftar. Ini memberikan keuntungan kinerja untuk dihapus dari akhir daftar, karena tidak perlumemmove
setiap item setelah Anda menghapus - kembali satu langkah (1) .Untuk pemindahan satu kali saja, perbedaan kinerja mungkin dapat diterima, tetapi jika Anda memiliki daftar besar dan perlu menghapus banyak item - Anda mungkin akan melihat peningkatan kinerja.
Meskipun harus diakui, dalam kasus ini, melakukan pencarian daftar lengkap kemungkinan akan menjadi hambatan kinerja juga, kecuali item sebagian besar di bagian depan daftar.
Metode ini dapat digunakan untuk penghapusan yang lebih efisien,
selama pemesanan ulang daftar dapat diterima. (2)
Anda mungkin ingin menghindari kesalahan saat
item
tidak ada dalam daftar.set
, terutama jika daftar tersebut tidak dimaksudkan untuk menyimpan duplikat.Namun dalam praktiknya Anda mungkin perlu menyimpan data yang bisa berubah yang tidak dapat ditambahkan ke file
set
. Periksa juga btree's jika data dapat dipesan.sumber
Eek, jangan lakukan hal yang rumit :)
Hanya
filter()
tag Anda.bool()
kembaliFalse
untuk string kosong, jadi alih-alihkamu harus menulis
atau lebih baik lagi, letakkan logika ini di dalam
striplist()
sehingga tidak mengembalikan string kosong di tempat pertama.sumber
striplist
fungsi saya , bagaimana saya memasukkan solusi Anda: def striplist (l): "" "strip whitespaces dari string dalam daftar l" "" return ([x.strip () untuk x in l])[x.strip() for x in l if x.strip()]
atau menggunakan Python built-inmap
danfilter
fungsi seperti ini:filter(bool, map(str.strip, l))
. Jika Anda ingin menguji itu, mengevaluasi ini di interpreter interaktif:filter(bool, map(str.strip, [' a', 'b ', ' c ', '', ' ']))
.None
bukanbool
untuk argumen pertama sudah cukup.Berikut ini pendekatan satu-liner lain untuk dibuang di sana:
Itu tidak membuat salinan daftar, tidak membuat beberapa melewati seluruh daftar, tidak memerlukan penanganan pengecualian tambahan, dan mengembalikan objek yang cocok atau Tidak ada jika tidak ada kecocokan. Satu-satunya masalah adalah itu membuat pernyataan panjang.
Secara umum, ketika mencari solusi satu-liner yang tidak membuang pengecualian, next () adalah cara untuk pergi, karena itu salah satu dari beberapa fungsi Python yang mendukung argumen default.
sumber
Yang harus Anda lakukan adalah ini
tetapi metode itu memiliki masalah. Anda harus meletakkan sesuatu di tempat kecuali jadi saya menemukan ini:
sumber