Cara menghapus elemen dari daftar berdasarkan indeks

1506

Bagaimana cara menghapus elemen dari daftar menurut indeks dengan Python?

Saya menemukan list.removemetode, tetapi katakan saya ingin menghapus elemen terakhir, bagaimana saya melakukan ini? Sepertinya default menghapus pencarian daftar, tetapi saya tidak ingin pencarian dilakukan.

Joan Venge
sumber
10
@smci: Daftar Python adalah berbasis array: untuk menghapus item di tengah, Anda harus memindahkan semua item di sebelah kanan untuk menghilangkan celah yang mengapa itu O(n)dalam operasi waktu. deque()menyediakan operasi yang efisien di kedua ujungnya tetapi tidak memberikan O (1) penyisipan / pencarian / penghapusan di tengah.
jfs
@JFSebastian: implementasi cPython, ya, terima kasih telah memperbaiki saya. Secara ketat spesifikasi bahasa tidak menentukan cara mengimplementasikan daftar, implementasi alternatif dapat memilih untuk menggunakan daftar tertaut.
smci
@smci: tidak ada implementasi Python praktis akan menggunakan O(n)akses indeks a[i](karena tertaut-daftar). Catatan: implementasi berbasis array menyediakan O(1)akses indeks.
jfs
@ JSFSebastian: tentu saja. Saya hanya mencatat bahwa spesifikasi bahasa tidak mendefinisikan ini , ini masalah implementasi. (Saya terkejut menemukan bahwa ternyata tidak.)
smci
@smci jika Anda menargetkan secara luas, saya tidak yakin bagaimana Anda bisa berharap untuk mengoptimalkan apa pun.
Nick T

Jawaban:

1741

Gunakan deldan tentukan indeks elemen yang ingin Anda hapus:

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del a[-1]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8]

Juga mendukung irisan:

>>> del a[2:4]
>>> a
[0, 1, 4, 5, 6, 7, 8, 9]

Ini bagian dari tutorial.

Neil Chowdhury
sumber
53
Terima kasih, apa perbedaan antara pop dan del?
Joan Venge
37
del kelebihan beban. Misalnya del a menghapus seluruh daftar
Brian R. Bondy
34
contoh lain del a [2: 4], menghapus elemen 2 dan 3
Brian R. Bondy
307
pop () mengembalikan elemen yang ingin Anda hapus. del just delete is.
13
Saya tidak dapat melihat bukti "daftar tertaut" di sana. Lihatlah svn.python.org/projects/python/trunk/Objects/listobject.c bagaimana PyList_GetItem()dasarnya mengembalikan ((PyListObject *)op) -> ob_item[i];- ielemen array.
glglgl
649

Anda mungkin ingin pop:

a = ['a', 'b', 'c', 'd']
a.pop(1)

# now a is ['a', 'c', 'd']

Secara default, poptanpa argumen apa pun menghapus item terakhir:

a = ['a', 'b', 'c', 'd']
a.pop()

# now a is ['a', 'b', 'c']
Jarret Hardie
sumber
105
Jangan lupa pop (-1). Ya, ini adalah default, tapi saya lebih suka jadi saya tidak harus mengingat pop end yang digunakan secara default.
S.Lott
282
Saya tidak setuju. Jika Anda tahu etimologi programmer "pop" (ini adalah operasi yang menghapus dan mengembalikan bagian atas struktur data 'stack'), maka pop()dengan sendirinya sangat jelas, sementara pop(-1)berpotensi membingungkan justru karena berlebihan.
coredumperror
a.pop (-1) untuk menghapus yang terakhir?
zx1986
14
@ zx1986 popdalam sebagian besar bahasa pemrograman biasanya menghapus item terakhir, seperti halnya dalam Python. Jadi apakah Anda menentukan -1 atau tidak sama dengan itu.
Pascal
30
Omong-omong, pop()mengembalikan elemen apa pun yang dihapusnya.
Bob Stein
136

Seperti orang lain disebutkan pop dan del adalah yang cara efisien untuk menghapus item dari indeks yang diberikan. Namun hanya demi penyelesaian (karena hal yang sama dapat dilakukan melalui banyak cara dengan Python):

Menggunakan irisan (ini tidak dilakukan untuk menghapus item dari daftar asli):

(Juga ini akan menjadi metode yang paling tidak efisien ketika bekerja dengan daftar Python, tetapi ini bisa berguna (tapi tidak efisien, saya tegaskan kembali) ketika bekerja dengan objek yang ditentukan pengguna yang tidak mendukung pop, belum mendefinisikan a __getitem__):

>>> a = [1, 2, 3, 4, 5, 6]
>>> index = 3 # Only positive index

>>> a = a[:index] + a[index+1 :]
# a is now [1, 2, 3, 5, 6]

Catatan: Harap dicatat bahwa metode ini tidak mengubah daftar di tempat seperti popdan del. Alih-alih itu membuat dua salinan daftar (satu dari awal sampai indeks tetapi tanpa itu ( a[:index]) dan satu setelah indeks sampai elemen terakhir ( a[index+1:])) dan membuat objek daftar baru dengan menambahkan keduanya. Ini kemudian dipindahkan ke variabel daftar ( a). Objek daftar lama karenanya direferensi dan karenanya sampah dikumpulkan (asalkan objek daftar asli tidak dirujuk oleh variabel apa pun selain a).

Ini membuat metode ini sangat tidak efisien dan juga dapat menghasilkan efek samping yang tidak diinginkan (terutama ketika variabel lain menunjuk ke objek daftar asli yang tetap tidak dimodifikasi).

Terima kasih kepada @MarkDickinson karena menunjukkan ini ...

Ini jawaban Stack Overflow menjelaskan konsep mengiris.

Perhatikan juga bahwa ini hanya berfungsi dengan indeks positif.

Saat menggunakan dengan objek, __getitem__ metode harus didefinisikan dan yang lebih penting __add__metode harus didefinisikan untuk mengembalikan objek yang berisi item dari kedua operan.

Intinya, ini bekerja dengan objek apa pun yang definisi kelasnya seperti:

class foo(object):
    def __init__(self, items):
        self.items = items

    def __getitem__(self, index):
        return foo(self.items[index])

    def __add__(self, right):
        return foo( self.items + right.items )

Ini bekerja dengan list yang mendefinisikan __getitem__dan __add__metode.

Perbandingan tiga cara dalam hal efisiensi:

Anggaplah yang berikut ini sudah ditentukan sebelumnya:

a = range(10)
index = 3

Itu del object[index] Metode:

Sejauh ini metode yang paling efisien. Berhasil semua objek yang mendefinisikan a__del__ metode.

Pembongkarannya adalah sebagai berikut:

Kode:

def del_method():
    global a
    global index
    del a[index]

Membongkar:

 10    0 LOAD_GLOBAL     0 (a)
       3 LOAD_GLOBAL     1 (index)
       6 DELETE_SUBSCR   # This is the line that deletes the item
       7 LOAD_CONST      0 (None)
      10 RETURN_VALUE
None

pop metode:

Itu kurang efisien daripada metode del dan digunakan ketika Anda perlu mendapatkan item yang dihapus.

Kode:

def pop_method():
    global a
    global index
    a.pop(index)

Membongkar:

 17     0 LOAD_GLOBAL     0 (a)
        3 LOAD_ATTR       1 (pop)
        6 LOAD_GLOBAL     2 (index)
        9 CALL_FUNCTION   1
       12 POP_TOP
       13 LOAD_CONST      0 (None)
       16 RETURN_VALUE

Iris dan tambahkan metode.

Paling tidak efisien.

Kode:

def slice_method():
    global a
    global index
    a = a[:index] + a[index+1:]

Membongkar:

 24     0 LOAD_GLOBAL    0 (a)
        3 LOAD_GLOBAL    1 (index)
        6 SLICE+2
        7 LOAD_GLOBAL    0 (a)
       10 LOAD_GLOBAL    1 (index)
       13 LOAD_CONST     1 (1)
       16 BINARY_ADD
       17 SLICE+1
       18 BINARY_ADD
       19 STORE_GLOBAL   0 (a)
       22 LOAD_CONST     0 (None)
       25 RETURN_VALUE
None

Catatan: Dalam ketiga disassemble mengabaikan dua baris terakhir yang pada dasarnya adalah return None. Juga dua baris pertama memuat nilai global adan index.

RV Raghav
sumber
4
Metode pengirisan Anda tidak menghapus elemen dari daftar: melainkan membuat objek daftar baru yang berisi semua kecuali entri ke-i dari daftar asli. Daftar asli dibiarkan tidak dimodifikasi.
Mark Dickinson
@MarkDickinson Sudah mengedit jawaban untuk mengklarifikasi yang sama ... Tolong beri tahu saya jika terlihat bagus sekarang?
Raghav RV
6
Mungkin jawabannya tidak sepenuhnya pada topik, tetapi metode pengindeksan berguna jika Anda perlu menghilangkan item dari objek yang tidak dapat diubah, seperti tuple. pop () dan del () tidak akan berfungsi dalam kasus itu.
Caleb
6
@ rvraghav93 dari semua metode yang disajikan selama seluruh posting, a = a[:index] + a[index+1 :]-trick adalah savest, ketika datang ke daftar besar. Semua metode lain berakhir di jalan buntu. Jadi terima kasih banyak
user3085931
3
Memang Markus, kamu pemarah. Jawaban ini adalah yang saya sukai karena itu benar-benar pedagogis. Saya paling banyak belajar dari jawaban ini dan detail desassembly yang disediakan dan dampaknya pada kinerja. Ditambah metode mengiris, ya, buat objek lain, tapi sekarang ditentukan dan kadang-kadang itu juga yang Anda butuhkan.
Yohan Obadia
52

popjuga berguna untuk menghapus dan menyimpan item dari daftar. Di mana delsebenarnya membuang item.

>>> x = [1, 2, 3, 4]

>>> p = x.pop(1)
>>> p
    2
pembuat perahu
sumber
24

Jika Anda ingin menghapus elemen posisi tertentu dalam daftar, seperti 2, 3, dan 7. kamu tidak bisa menggunakan

del my_list[2]
del my_list[3]
del my_list[7]

Karena setelah Anda menghapus elemen kedua, elemen ketiga yang Anda hapus sebenarnya adalah elemen keempat dalam daftar asli. Anda dapat memfilter elemen 2, 3 dan 7 di daftar asli dan mendapatkan daftar baru, seperti di bawah ini:

new list = [j for i, j in enumerate(my_list) if i not in [2, 3, 7]]
xiaojia zhang
sumber
19

Ini tergantung pada apa yang ingin Anda lakukan.

Jika Anda ingin mengembalikan elemen yang Anda hapus, gunakan pop():

>>> l = [1, 2, 3, 4, 5]
>>> l.pop(2)
3
>>> l
[1, 2, 4, 5]

Namun, jika Anda hanya ingin menghapus suatu elemen, gunakan del:

>>> l = [1, 2, 3, 4, 5]
>>> del l[2]
>>> l
[1, 2, 4, 5]

Selain itu, delmemungkinkan Anda untuk menggunakan irisan (misalnya del[2:]).

Neil Chowdhury
sumber
18

Secara umum, saya menggunakan metode berikut:

>>> myList = [10,20,30,40,50]
>>> rmovIndxNo = 3
>>> del myList[rmovIndxNo]
>>> myList
[10, 20, 30, 50]
Mayur Koshti
sumber
15

Namun cara lain untuk menghapus elemen dari daftar dengan indeks.

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# remove the element at index 3
a[3:4] = []
# a is now [0, 1, 2, 4, 5, 6, 7, 8, 9]

# remove the elements from index 3 to index 6
a[3:7] = []
# a is now [0, 1, 2, 7, 8, 9]

a [x: y] menunjuk ke elemen-elemen dari indeks xke y-1. Ketika kami mendeklarasikan bagian daftar itu sebagai daftar kosong ( []), elemen-elemen itu dihapus.

Andreas Chatzivasileiadis
sumber
14

Anda bisa mencari item yang ingin Anda hapus. Ini sangat sederhana. Contoh:

    letters = ["a", "b", "c", "d", "e"]
    letters.remove(letters[1])
    print(*letters) # Used with a * to make it unpack you don't have to (Python 3.x or newer)

Output: acde

SollyBunny
sumber
6
Saya suka solusi ini, tetapi tentu saja mengasumsikan daftar Anda tidak memiliki duplikat.
tommy.carstensen
11

Gunakan kode berikut untuk menghapus elemen dari daftar:

list = [1, 2, 3, 4]
list.remove(1)
print(list)

output = [2, 3, 4]

Jika Anda ingin menghapus data elemen indeks dari daftar gunakan:

list = [1, 2, 3, 4]
list.remove(list[2])
print(list)
output : [1, 2, 4]
jitsm555
sumber
2
Dilengkapi dengan peringatan bahwa daftar Anda tidak dapat berisi duplikat.
tommy.carstensen
3
Ini bukan menghapus dengan indeks, tetapi menghapus dengan nilai yang cocok. Itu mungkin informasi berharga bagi sebagian orang yang berkunjung ke sini, tetapi tidak mencoba menjawab pertanyaan OPs sama sekali.
Anthon
8

Seperti disebutkan sebelumnya, praktik terbaik adalah del (); atau pop () jika Anda perlu tahu nilainya.

Solusi alternatif adalah menumpuk kembali hanya elemen-elemen yang Anda inginkan:

    a = ['a', 'b', 'c', 'd'] 

    def remove_element(list_,index_):
        clipboard = []
        for i in range(len(list_)):
            if i is not index_:
                clipboard.append(list_[i])
        return clipboard

    print(remove_element(a,2))

    >> ['a', 'b', 'd']

eta: hmm ... tidak akan berfungsi pada nilai indeks negatif, akan direnungkan dan diperbarui

Saya seharusnya

if index_<0:index_=len(list_)+index_

akan menambalnya ... tapi tiba-tiba ide ini tampaknya sangat rapuh. Eksperimen pemikiran yang menarik. Tampaknya harus ada cara yang 'tepat' untuk melakukan ini dengan append () / daftar pemahaman.

merenungkan

kehadiran kecil
sumber
1
Versi Python mana yang memiliki fungsi del()? Untuk fungsi itu Anda memberikan daftar sebagai argumen pertama untuk fungsi itu dan kemudian indeks, atau indeks pertama dan kemudian daftar? Apakah itu mengembalikan argumen daftar tanpa item, atau apakah itu menghapus tempat. Saya tahu tentang delpernyataan itu, tetapi bukan tentang fungsi dengan nama yang sama.
Anthon
8

Kedengarannya tidak seperti Anda bekerja dengan daftar daftar, jadi saya akan membuat ini singkat. Anda ingin menggunakan pop karena itu akan menghapus elemen bukan elemen yang daftar, Anda harus menggunakan del untuk itu. Untuk memanggil elemen terakhir dalam python itu "-1"

>>> test = ['item1', 'item2']
>>> test.pop(-1)
'item2'
>>> test
['item1']
Mo Ali
sumber
1
pop()dan delkeduanya menghapus elemen pada indeks yang disediakan, terlepas dari apakah elemen itu sendiri daftar atau tidak. a = [1, [2, 3], 4]; del a[1]; b = [1, [2, 3], 4]; b.pop(1); assert a == b
Anthon
8

l - daftar nilai; kita harus menghapus indeks dari daftar inds2rem .

l = range(20)
inds2rem = [2,5,1,7]
map(lambda x: l.pop(x), sorted(inds2rem, key = lambda x:-x))

>>> l
[0, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Jo Ja
sumber
tidak bekerja, jawabannya adalah <map at 0x7f4d54109a58>. dan l adalah kisaran (0,20)
Hitesh
7

Gunakan fungsi "del" :

del listName[-N]

Misalnya, jika Anda ingin menghapus 3 item terakhir, kode Anda harus:

del listName[-3:]

Misalnya, jika Anda ingin menghapus 8 item terakhir, kode Anda harus:

del listName[-8:]
lloydyu24
sumber
2
deladalah sebuah pernyataan . Jika itu sebuah fungsi, Anda harus menulisdel(listame[-N])
Anthon
7

Telah disebutkan bagaimana menghapus satu elemen dari daftar dan keuntungan apa yang dimiliki metode yang berbeda. Perhatikan, bagaimanapun, menghapus beberapa elemen berpotensi menyebabkan kesalahan:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in indices:
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 7, 9]

Elemen 3 dan 8 (bukan 3 dan 7) dari daftar asli telah dihapus (karena daftar itu dipersingkat selama loop), yang mungkin bukan maksudnya. Jika Anda ingin menghapus beberapa indeks dengan aman, Anda harus menghapus elemen dengan indeks tertinggi terlebih dahulu, misalnya seperti ini:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in sorted(indices, reverse=True):
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 8, 9]
Kopfgeldjaeger
sumber
4

Atau jika beberapa indeks harus dihapus:

print([v for i,v in enumerate(your_list) if i not in list_of_unwanted_indexes])

Tentu saja bisa juga dilakukan:

print([v for i,v in enumerate(your_list) if i != unwanted_index])
U10-Maju
sumber
1
Mengapa Anda tidak mengurutkan daftar indeks dalam urutan terbalik dan kemudian menghapusnya satu per satu? Dengan begitu Anda tidak perlu membuat daftar baru.
Anthon
3

Anda dapat menggunakan del atau pop untuk menghapus elemen dari daftar berdasarkan indeks. Pop akan mencetak anggota yang dihapus dari daftar, sementara daftar menghapus anggota tersebut tanpa mencetaknya.

>>> a=[1,2,3,4,5]
>>> del a[1]
>>> a
[1, 3, 4, 5]
>>> a.pop(1)
 3
>>> a
[1, 4, 5]
>>> 
Aashutosh jha
sumber
3

Anda dapat menggunakan del atau pop, tetapi saya lebih suka del, karena Anda dapat menentukan indeks dan irisan, memberi pengguna lebih banyak kontrol atas data.

Misalnya, dimulai dengan daftar yang ditampilkan, seseorang dapat menghapus elemen terakhirnya dengan del irisan, dan kemudian seseorang dapat menghapus elemen terakhir dari hasil menggunakan pop.

>>> l = [1,2,3,4,5]
>>> del l[-1:]
>>> l
[1, 2, 3, 4]
>>> l.pop(-1)
4
>>> l
[1, 2, 3]
pyman
sumber