Apakah ada cara sederhana untuk menghapus elemen daftar berdasarkan nilai?


942
a = [1, 2, 3, 4]
b = a.index(6)

del a[b]
print(a)

Di atas menunjukkan kesalahan berikut:

Traceback (most recent call last):
  File "D:\zjm_code\a.py", line 6, in <module>
    b = a.index(6)
ValueError: list.index(x): x not in list

Jadi saya harus melakukan ini:

a = [1, 2, 3, 4]

try:
    b = a.index(6)
    del a[b]
except:
    pass

print(a)

Tetapi apakah tidak ada cara yang lebih sederhana untuk melakukan ini?


14
Anda menghitung indeks 6 dalam daftar Anda. Tapi 6 tidak ada dalam daftar Anda ... jadi apa yang seharusnya terjadi? :)
Johannes Charra

5
ini tidak ada hubungannya dengan menghapus nilai dalam daftar, karena kode Anda tidak mencapai pernyataan del. Mungkin Anda harus memberi judul ulang "bagaimana saya mendapatkan indeks nilai yang tidak ada dalam daftar. Jawaban yang jelas - Anda tidak bisa.
Dave Kirby

57
@ Selamat Yah, tidak juga. Dia ingin menghapus item dari daftar terlepas dari apakah itu ada atau tidak, tidak untuk mendapatkan indeks untuk item yang tidak ada. Pertanyaannya ditanyakan dengan baik.
ibz

Selain itu, tetapi telanjang exceptadalah praktik yang buruk . Gunakan except Exceptionminimal.
wjandrea

Jawaban:


1564

Untuk menghapus kejadian pertama suatu elemen dalam daftar, cukup gunakan list.remove:

>>> a = ['a', 'b', 'c', 'd']
>>> a.remove('b')
>>> print(a)
['a', 'c', 'd']

Pikiran bahwa itu tidak menghapus semua kemunculan elemen Anda. Gunakan pemahaman daftar untuk itu.

>>> a = [10, 20, 30, 40, 20, 30, 40, 20, 70, 20]
>>> a = [x for x in a if x != 20]
>>> print(a)
[10, 30, 40, 30, 40, 70]

144
Gagal jika elemen tidak ada dalam daftar. :)
ibz

21
Pemahaman daftar @ibz tidak gagal bahkan jika elemen tidak ada dalam daftar, bukan?
IsaacS

76
Untuk memperjelas bagi siapa pun yang membaca sepintas lalu, itu "gagal" dalam arti bahwa hal itu menimbulkan pengecualian ValueError.
Casey Falk

10
Pemahaman daftar mengubah referensi daftar jadi jika ada salinan referensi di suatu tempat, penghapusan tidak akan mengikuti.
Sebastien

Apa kerumitannya removeO (n)?
Rasmi Ranjan Nayak

184

Biasanya Python akan mengeluarkan Exception jika Anda menyuruhnya melakukan sesuatu yang tidak bisa, jadi Anda harus melakukannya:

if c in a:
    a.remove(c)

atau:

try:
    a.remove(c)
except ValueError:
    pass

Pengecualian tidak selalu merupakan hal yang buruk asalkan itu yang Anda harapkan dan tangani dengan benar.


9
Mencegah lebih baik daripada mengobati. Jika Anda dapat memeriksa kondisi luar biasa terlebih dahulu (contoh a), Anda harus melakukannya.
Gusdor

82
Sementara ini benar dalam bahasa lain, dalam Python itu "lebih mudah untuk meminta pengampunan daripada izin." docs.python.org/2/glossary.html#term-eafp
Dave Webb

6
@ Goddor: jika daftar dibagikan di antara utas-utas maka a.remove(c)mungkin akan gagal meskipun if c in acek ( adapat dimodifikasi di utas lain setelah c in acek tetapi sebelum a.remove(c)panggilan) try/exceptatau kunci dapat digunakan untuk menghindari kondisi balapan.
jfs

7
@ JSFSebastian jika daftar dibagi di antara utas dan Anda tidak menerapkan bagian kritis maka Anda memiliki masalah yang lebih besar.
Gusdor

4
@ Goddor, idiom Pythonique adalah mencoba tanpa memeriksa dan menangkap pengecualian jika itu terjadi. Ini lebih efisien (hanya satu pencarian, bukan dua), meskipun sedikit lebih buruk
Jeet

80

Anda dapat melakukan

a=[1,2,3,4]
if 6 in a:
    a.remove(6)

tetapi di atas perlu mencari 6 dalam daftar 2 kali, jadi coba kecuali akan lebih cepat

try:
    a.remove(6)
except:
    pass

55

Mempertimbangkan:

a = [1,2,2,3,4,5]

Untuk menghapus semua kejadian, Anda bisa menggunakan fungsi filter dengan python. Sebagai contoh, akan terlihat seperti:

a = list(filter(lambda x: x!= 2, a))

Jadi, itu akan menjaga semua elemen a != 2.

Untuk hanya mengambil salah satu item yang digunakan

a.remove(2)

Mengapa Anda membungkus yang filter()lain list()? Menurut manual, itu sudah mengembalikan daftar.
Olaf Dietsche

8
@ OlafDietsche Dalam Python 3.x, ia mengembalikan objek filter (dalam 2.x, ia mengembalikan daftar), jadi saya harus melemparkan "a" ke daftar agar dapat memiliki fungsionalitas.
mathwizurd

17

Berikut cara melakukannya di tempat (tanpa pemahaman daftar):

def remove_all(seq, value):
    pos = 0
    for item in seq:
        if item != value:
           seq[pos] = item
           pos += 1
    del seq[pos:]

Sangat pintar - saya sangat suka ini - sayangnya sepertinya tidak efisien seperti jawaban paling populer. solusi gil sebenarnya jauh lebih cepat untuk daftar raksasa dengan hanya beberapa kemunculan nilai yang ingin Anda hapus.
Larold

1
@Larold Cara tercepat adalah pertanyaan terpisah. Uang saya masuk daftar pemahaman dalam kasus umum. Solusi ini harus berkinerja sangat baik jika nilainya sering dalam daftar input dan pemahaman daftar tidak digunakan. Coba Pypy, data numpy di Cython. [@ Gill jawaban O(n*n)tidak perlu (bandingkan 1e6 dan 1e12 - Anda tidak ingin mengambil risiko yang terakhir). while 1: L.remove(value)dan kembali ValueErrormungkin bekerja dengan baik dengan beberapa values atau daftar kecil di CPython.
jfs

13

Jika Anda tahu nilai apa yang harus dihapus, berikut ini cara sederhana (sesederhana yang dapat saya pikirkan):

a = [0, 1, 1, 0, 1, 2, 1, 3, 1, 4]
while a.count(1) > 0:
    a.remove(1)

Anda akan mendapatkannya [0, 0, 2, 3, 4]


4
Mengapa tidak digunakan while 1 in a:sebagai struktur loop?
TerminalDilettante

12
Di O(n^2)sinilah pemahaman akan terjadi O(n).
Fisikawan Gila

1
Tentu saja @MadPhysicist benar, dan versi TerminalDilettante jauh lebih pythonic, bahkan jika kita tidak peduli dengan kinerja. 2013 adalah saya baru mulai belajar Python dan saat ini saya cukup malu dengan apa yang saya tulis saat itu.
gil

11

Kemungkinan lain adalah menggunakan set daripada daftar, jika satu set berlaku di aplikasi Anda.

Yaitu jika data Anda tidak diurutkan, dan tidak memiliki duplikat, maka

my_set=set([3,4,2])
my_set.discard(1)

bebas dari kesalahan.

Seringkali daftar hanyalah wadah berguna untuk item yang sebenarnya tidak terurut. Ada pertanyaan yang menanyakan cara menghapus semua kemunculan elemen dari daftar. Jika Anda tidak ingin dupes di tempat pertama, sekali lagi satu set berguna.

my_set.add(3)

tidak mengubah my_set dari atas.


10

Seperti yang dinyatakan oleh banyak jawaban lain, list.remove()akan berhasil, tetapi melempar ValueErrorjika item tidak ada dalam daftar. Dengan python 3.4+, ada pendekatan yang menarik untuk menangani ini, menggunakan suppress contextmanager :

from contextlib import suppress
with suppress(ValueError):
    a.remove('b')

8

Menemukan nilai dalam daftar lalu menghapus indeks itu (jika ada) lebih mudah dilakukan dengan hanya menggunakan metode hapus daftar:

>>> a = [1, 2, 3, 4]
>>> try:
...   a.remove(6)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 3, 4]
>>> try:
...   a.remove(3)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 4]

Jika Anda sering melakukannya, Anda dapat membungkusnya dalam suatu fungsi:

def remove_if_exists(L, value):
  try:
    L.remove(value)
  except ValueError:
    pass

8

Contoh ini cepat dan akan menghapus semua instance nilai dari daftar:

a = [1,2,3,1,2,3,4]
while True:
    try:
        a.remove(3)
    except:
        break
print a
>>> [1, 2, 1, 2, 4]

2
jika Anda melakukan ini, Anda harus benar-benar hanya breakpada except ValueError.
Anthon

8

Dalam satu baris:

a.remove('b') if 'b' in a else None

terkadang bermanfaat.

Lebih mudah lagi:

if 'b' in a: a.remove('b')

7

Jika elemen Anda berbeda, maka perbedaan set sederhana akan dilakukan.

c = [1,2,3,4,'x',8,6,7,'x',9,'x']
z = list(set(c) - set(['x']))
print z
[1, 2, 3, 4, 6, 7, 8, 9]

2
Jika elemen Anda berbeda dan Anda tidak peduli tentang pesanan .
Tom Zych

2

Kita juga bisa menggunakan .pop:

>>> lst = [23,34,54,45]
>>> remove_element = 23
>>> if remove_element in lst:
...     lst.pop(lst.index(remove_element))
... 
23
>>> lst
[34, 54, 45]
>>> 

2

Timpa daftar dengan mengindeks semuanya kecuali elemen yang ingin Anda hapus

>>> s = [5,4,3,2,1]
>>> s[0:2] + s[3:]
[5, 4, 2, 1]

2

Dengan for for dan kondisi:

def cleaner(seq, value):    
    temp = []                      
    for number in seq:
        if number != value:
            temp.append(number)
    return temp

Dan jika Anda ingin menghapus beberapa, tetapi tidak semua:

def cleaner(seq, value, occ):
    temp = []
    for number in seq:
        if number == value and occ:
            occ -= 1
            continue
        else:
            temp.append(number)
    return temp

1
 list1=[1,2,3,3,4,5,6,1,3,4,5]
 n=int(input('enter  number'))
 while n in list1:
    list1.remove(n)
 print(list1)

Itu tanpa menggunakan fungsi filter
Ravikiran D

1

Katakan misalnya, kami ingin menghapus semua 1 dari x. Ini adalah bagaimana saya akan melakukannya:

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

Sekarang, ini adalah penggunaan praktis dari metode saya:

def Function(List, Unwanted):
    [List.remove(Unwanted) for Item in range(List.count(Unwanted))]
    return List
x = Function(x, 1)
print(x)

Dan ini adalah metode saya dalam satu baris:

[x.remove(1) for Item in range(x.count(1))]
print(x)

Keduanya menghasilkan ini sebagai output:

[2, 3, 2, 3, 2, 3]

Semoga ini membantu. PS, mohon perhatikan bahwa ini ditulis dalam versi 3.6.2, jadi Anda mungkin perlu menyesuaikannya untuk versi yang lebih lama.


1

Mungkin solusi Anda bekerja dengan ints, tetapi itu tidak berfungsi untuk saya dengan kamus.

Di satu sisi, hapus () tidak berfungsi untuk saya. Tapi mungkin itu bekerja dengan Tipe dasar. Saya kira kode di bawah ini juga cara untuk menghapus item dari daftar objek.

Di sisi lain, 'del' juga tidak berfungsi dengan baik. Dalam kasus saya, menggunakan python 3.6: ketika saya mencoba untuk menghapus elemen dari daftar di 'for' bucle dengan perintah 'del', python mengubah indeks dalam proses dan bucle berhenti sebelum waktunya sebelum waktu. Ini hanya berfungsi jika Anda menghapus elemen demi elemen secara terbalik urutan . Dengan cara ini Anda tidak mengubah indeks array elemen yang menunggu saat Anda akan melewatinya

Kemudian, saya menggunakan:

c = len(list)-1
for element in (reversed(list)):
    if condition(element):
        del list[c]
    c -= 1
print(list)

di mana 'daftar' seperti [{'key1': value1 '}, {' key2 ': value2}, {' key3 ': value3}, ...]

Anda juga dapat melakukan lebih banyak pythonic menggunakan enumerate:

for i, element in enumerate(reversed(list)):
    if condition(element):
        del list[(i+1)*-1]
print(list)

0
arr = [1, 1, 3, 4, 5, 2, 4, 3]

# to remove first occurence of that element, suppose 3 in this example
arr.remove(3)

# to remove all occurences of that element, again suppose 3
# use something called list comprehension
new_arr = [element for element in arr if element!=3]

# if you want to delete a position use "pop" function, suppose 
# position 4 
# the pop function also returns a value
removed_element = arr.pop(4)

# u can also use "del" to delete a position
del arr[4]

0

Ini menghapus semua instance dari "-v"array sys.argv, dan tidak mengeluh jika tidak ada instance ditemukan:

while "-v" in sys.argv:
    sys.argv.remove('-v')

Anda dapat melihat kode dalam aksi, dalam file bernama speechToText.py:

$ python speechToText.py -v
['speechToText.py']

$ python speechToText.py -x
['speechToText.py', '-x']

$ python speechToText.py -v -v
['speechToText.py']

$ python speechToText.py -v -v -x
['speechToText.py', '-x']

-1

ini jawaban saya, gunakan saja sementara dan untuk

def remove_all(data, value):
    i = j = 0
    while j < len(data):
        if data[j] == value:
            j += 1
            continue
        data[i] = data[j]
        i += 1
        j += 1
    for x in range(j - i):
        data.pop()
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.