Jawaban ini awalnya ditulis sebagai jawaban atas pertanyaan yang telah ditandai sebagai duplikat:
Menghapus koordinat dari daftar di python
Ada dua masalah dalam kode Anda:
1) Saat menggunakan remove (), Anda mencoba menghapus integer sedangkan Anda perlu menghapus tuple.
2) Loop for akan melewatkan item dalam daftar Anda.
Mari kita jalankan apa yang terjadi ketika kami mengeksekusi kode Anda:
>>> L1 = [(1,2), (5,6), (-1,-2), (1,-2)]
>>> for (a,b) in L1:
... if a < 0 or b < 0:
... L1.remove(a,b)
...
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
TypeError: remove() takes exactly one argument (2 given)
Masalah pertama adalah Anda memberikan 'a' dan 'b' untuk menghapus (), tetapi menghapus () hanya menerima argumen tunggal. Jadi bagaimana kami bisa menghapus () agar berfungsi dengan baik dengan daftar Anda? Kami perlu mencari tahu apa setiap elemen daftar Anda. Dalam hal ini, masing-masing adalah tuple. Untuk melihat ini, mari kita akses satu elemen daftar (pengindeksan dimulai pada 0):
>>> L1[1]
(5, 6)
>>> type(L1[1])
<type 'tuple'>
Aha! Setiap elemen L1 sebenarnya adalah tuple. Jadi itu yang harus kita lewati untuk menghapus (). Tuple dalam python sangat mudah, mereka hanya dibuat dengan menyertakan nilai dalam tanda kurung. "a, b" bukan tuple, tapi "(a, b)" adalah tuple. Jadi kami memodifikasi kode Anda dan menjalankannya lagi:
# The remove line now includes an extra "()" to make a tuple out of "a,b"
L1.remove((a,b))
Kode ini berjalan tanpa kesalahan, tetapi mari kita lihat daftar yang dihasilkannya:
L1 is now: [(1, 2), (5, 6), (1, -2)]
Mengapa (1, -2) masih ada di daftar Anda? Ternyata memodifikasi daftar sambil menggunakan loop untuk beralih lebih dari itu adalah ide yang sangat buruk tanpa perawatan khusus. Alasan bahwa (1, -2) tetap dalam daftar adalah bahwa lokasi setiap item dalam daftar berubah antara iterasi dari for loop. Mari kita lihat apa yang terjadi jika kita memberi kode yang lebih panjang pada daftar di atas:
L1 = [(1,2),(5,6),(-1,-2),(1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
### Outputs:
L1 is now: [(1, 2), (5, 6), (1, -2), (3, 4), (5, 7), (2, 1), (5, -1), (0, 6)]
Seperti yang dapat Anda simpulkan dari hasil itu, setiap kali pernyataan bersyarat mengevaluasi ke true dan item daftar dihapus, iterasi loop berikutnya akan melewati evaluasi item berikutnya dalam daftar karena nilainya sekarang berada di indeks yang berbeda.
Solusi paling intuitif adalah menyalin daftar, kemudian beralih ke daftar asli dan hanya memodifikasi salinan. Anda dapat mencoba melakukannya seperti ini:
L2 = L1
for (a,b) in L1:
if a < 0 or b < 0 :
L2.remove((a,b))
# Now, remove the original copy of L1 and replace with L2
print L2 is L1
del L1
L1 = L2; del L2
print ("L1 is now: ", L1)
Namun, hasilnya akan sama dengan sebelumnya:
'L1 is now: ', [(1, 2), (5, 6), (1, -2), (3, 4), (5, 7), (2, 1), (5, -1), (0, 6)]
Ini karena ketika kita membuat L2, python tidak benar-benar membuat objek baru. Sebaliknya, itu hanya mereferensikan L2 ke objek yang sama dengan L1. Kami dapat memverifikasi ini dengan 'is' yang berbeda dari sekadar "sama dengan" (==).
>>> L2=L1
>>> L1 is L2
True
Kita dapat membuat salinan yang benar menggunakan copy.copy (). Kemudian semuanya berfungsi seperti yang diharapkan:
import copy
L1 = [(1,2), (5,6),(-1,-2), (1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
L2 = copy.copy(L1)
for (a,b) in L1:
if a < 0 or b < 0 :
L2.remove((a,b))
# Now, remove the original copy of L1 and replace with L2
del L1
L1 = L2; del L2
>>> L1 is now: [(1, 2), (5, 6), (3, 4), (5, 7), (2, 1), (0, 6)]
Akhirnya, ada satu solusi yang lebih bersih daripada harus membuat salinan L1 yang sama sekali baru. Fungsi terbalik ():
L1 = [(1,2), (5,6),(-1,-2), (1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
for (a,b) in reversed(L1):
if a < 0 or b < 0 :
L1.remove((a,b))
print ("L1 is now: ", L1)
>>> L1 is now: [(1, 2), (5, 6), (3, 4), (5, 7), (2, 1), (0, 6)]
Sayangnya, saya tidak bisa menjelaskan cara membalikkan () bekerja. Ini mengembalikan objek 'listreverseiterator' ketika daftar diteruskan ke sana. Untuk tujuan praktis, Anda dapat menganggapnya sebagai membuat salinan argumennya yang terbalik. Ini solusi yang saya rekomendasikan.