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.


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.


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']

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.


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

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]]

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:]).


18

Secara umum, saya menggunakan metode berikut:

>>> myList = [10,20,30,40,50]
>>> rmovIndxNo = 3
>>> del myList[rmovIndxNo]
>>> myList
[10, 20, 30, 50]

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.


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


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]

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


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']

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]

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:]

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]

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])

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]
>>> 

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]
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.