Bir liste öğesini değere göre silmenin basit bir yolu var mı?


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

del a[b]
print(a)

Yukarıdakiler aşağıdaki hatayı gösterir:

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

Bu yüzden bunu yapmak zorundayım:

a = [1, 2, 3, 4]

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

print(a)

Ama bunu yapmanın daha basit bir yolu yok mu?


14
Listenizdeki 6 dizinini hesaplarsınız. Ama 6 listenizde değil ... Peki ne olacak? :)
Johannes Charra

5
kodunuz del ifadesine ulaşmadığından, bunun bir listedeki bir değeri silmekle ilgisi yoktur. Belki tekrar vermelisin "listede olmayan bir değerin indeksini nasıl alabilirim. Açık cevap - yapamazsın.
Dave Kirby

57
@Dave Pek değil. Var olmayan veya olmayan bir öğeyi listeden silmek, var olmayan bir öğenin dizinini almak istemez. Soru iyi sorulmuştur.
ibz

Konu yanında, ama çıplak exceptkötü bir uygulamadır . except ExceptionEn az kullanın .
wjandrea

Yanıtlar:


1564

Bir öğenin listedeki ilk oluşumunu kaldırmak için şunu kullanın list.remove:

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

Öğenizin tüm örneklerini kaldırmayacağını unutmayın. Bunun için bir liste kavrayışı kullanın.

>>> 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
Öğe listede yoksa başarısız olur. :)
ibz

21
@ iBz liste anlama, öğe listede olmasa bile başarısız olmaz, değil mi?
IsaacS

76
Kaydırma yapan herkes için açıklığa kavuşturmak için, bir ValueError istisnası oluşturması anlamında "başarısız" olur.
Casey Falk

10
Liste kavraması liste başvurusunu değiştirir, bu nedenle bir yerde referansın bir kopyası varsa, kaldırma işlemi takip edilmez.
Sebastien

removeO (n) karmaşıklığı nedir ?
Rasmi Ranjan Nayak

184

Genellikle yapamayacağı bir şey yapmasını söylerseniz Python bir İstisna atar, böylece aşağıdakilerden birini yapmanız gerekir:

if c in a:
    a.remove(c)

veya:

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

Bir İstisna, beklediğiniz ve uygun şekilde işlediğiniz sürece kötü bir şey olmak zorunda değildir.


9
Korunma tedaviden daha iyidir. Önce istisnai durumları kontrol edebiliyorsanız (örnek a), yapmalısınız.
Gusdor

82
Bu diğer dillerde geçerli olsa da, Python'da "affetmekten izin istemekten daha kolaydır." docs.python.org/2/glossary.html#term-eafp
Dave Webb

6
@Gusdor: Liste iş parçacıkları arasında paylaşılırsa, a.remove(c)yine de if c in akontrole rağmen başarısız olabilir (kontrolden asonra c in aancak a.remove(c)çağrıdan önce başka bir evrede değiştirilebilir ). try/exceptya da kilitler yarış koşullarından kaçınmak için kullanılabilir.
jfs

7
@JFSebastian bir iş parçacığı arasında paylaşılıyor ve kritik bölümler uygulamıyorsanız daha büyük sorunlarınız var.
Gusdor

4
@Gusdor, Pythonique deyimi kontrol etmeden denemek ve meydana gelirse istisnayı yakalamaktır. Biraz daha çirkin de olsa daha verimli (iki yerine sadece bir arama)
Jeet

80

Yapabilirsin

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

ancak yukarıdaki listede 2 kez arama yapmanız gerekiyor, bu yüzden daha hızlı olurdu hariç deneyin

try:
    a.remove(6)
except:
    pass

55

Düşünmek:

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

Tüm olayları ortadan kaldırmak için python'da filtre işlevini kullanabilirsiniz. Örneğin, şöyle görünecektir:

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

Böylece, tüm unsurlarını koruyacaktır a != 2.

Öğelerden birini çıkarmak için

a.remove(2)

Neden bir filter()başkasına sarıyorsun list()? El kitabına göre, zaten bir liste döndürüyor.
Olaf Dietsche

8
@OlafDietsche Python 3.x içinde, bir filtre nesnesi döndürür (2.x, bir liste döndürür), bu yüzden herhangi bir işlevsellik olması için bir listeye "a" döküm gerekir.
mathwizurd

17

Yerinde nasıl yapılacağı (liste kavrama olmadan):

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

Çok zeki - bunu gerçekten seviyorum - maalesef en popüler cevap kadar verimsiz görünüyor. gil'in çözümü, kaldırmak istediğiniz değerin yalnızca birkaç tekrarına sahip dev listeler için çok daha hızlıdır.
Larold

1
@Larold En hızlı yol ayrı bir soru olurdu. Genel durumda param liste kavrayışında. Giriş listesinde değer sıksa ve liste kavrama kullanılmıyorsa bu çözüm gerçekten iyi çalışmalıdır. Cython'da Pypy, numpy verilerini deneyin. [@ Gill'in cevabı O(n*n)gereksizdir (1e6 ve 1e12'yi karşılaştırın - ikincisini riske atmak istemezsiniz). while 1: L.remove(value)ve geri dönüş CPython'daki ValueErrorbirkaç values veya küçük listeyle iyi sonuç verebilir .
jfs

13

Hangi değerin silineceğini biliyorsanız, işte basit bir yol (yine de düşünebildiğim kadar basit):

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

Alacaksınız [0, 0, 2, 3, 4]


4
Neden while 1 in a:döngü yapısı olarak kullanılmıyor?
TerminalDilettante

12
İşte bu O(n^2)noktada bir kavrayış olurdu O(n).
Mad Physicist

1
Elbette @MadPhysicist doğrudur ve TerminalDilettante'nin sürümü, performansı önemsemesek bile çok daha pitoniktir. 2013 Python'u yeni öğrenmeye başladım ve bugünlerde o zamanlar yazdıklarımdan sık sık utanıyorum.
gil

11

Başka bir olasılık, uygulamanızda bir küme varsa, liste yerine bir küme kullanmaktır.

IE verileriniz sipariş edilmemişse ve kopyaları yoksa,

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

hatasızdır.

Genellikle bir liste aslında sıralanmamış öğeler için kullanışlı bir kaptır. Bir öğenin tüm oluşumlarını listeden nasıl kaldıracağınızı soran sorular vardır. İlk etapta dupes istemiyorsanız, bir set daha kullanışlıdır.

my_set.add(3)

my_set öğesini yukarıdan değiştirmez.


10

Diğer birçok cevapla belirtildiği gibi list.remove(), işe yarayacak, ancak ValueErroröğe listede değilse bir atacaktır . Piton 3.4+ ile kullanarak, bu işleme karşı ilginç bir yaklaşım var bastırmak contextmanager :

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

8

Bir listede bir değer bulmak ve ardından (varsa) bu dizini silmek, listenin kaldırma yöntemini kullanarak daha kolaydır:

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

Bunu sık sık yaparsanız, bir işlevde tamamlayabilirsiniz:

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

8

Bu örnek hızlıdır ve bir değerin tüm örneklerini listeden siler:

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

2
bunu yaparsanız gerçekten sadece breaküzerinde gerekir except ValueError.
Anthon

8

Bir satırda:

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

bazen yararlı olur.

Daha da kolay:

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

7

Öğeleriniz farklıysa, basit bir set farkı olacaktır.

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
Elemanlarınız farklıysa ve düzeni önemsemiyorsanız .
Tom Zych

2

Ayrıca .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

Kaldırmak istediğiniz öğeler dışında her şeyi dizine ekleyerek listenin üzerine yazın

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

2

For döngüsü ve koşuluyla:

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

Ve bazılarını kaldırmak istiyorsanız, ancak hepsini kaldırmak istemiyorsanız:

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)

Filtre işlevini kullanmadan
Ravikiran D

1

Diyelim ki x'in tüm 1'lerini kaldırmak istiyoruz. Ben böyle giderdim:

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

Şimdi, bu yöntemimin pratik bir kullanımı:

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

Ve bu tek bir satırda benim yöntem:

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

Her ikisi de bunu bir çıktı olarak verir:

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

Bu yardımcı olur umarım. PS, bunun 3.6.2 sürümünde yazıldığını unutmayın, bu nedenle eski sürümler için ayarlamanız gerekebilir.


1

Belki çözümleriniz ints ile çalışır, ama benim için sözlüklerle işe yaramıyor.

Bir yandan, remove () benim için çalışmadı. Ama belki temel tiplerle çalışır. Ben kod feryat da nesneler listesinden öğeleri kaldırmak için bir yol sanırım.

Öte yandan, 'del' de düzgün çalışmadı. Benim durumumda, python 3.6 kullanarak: 'del' komutuyla bir 'for' dizesindeki bir öğeyi silmeye çalıştığımda, python işlemdeki dizini değiştirir ve bucle zamanından önce durur. Yalnızca öğeleri ters sırayla sildiğinizde çalışır . Bu şekilde, beklemedeki öğeler dizini dizinini geçerken değiştirmezsiniz.

Sonra kullandım:

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

burada 'liste' [{'anahtar1': değer1 '}, {' anahtar2 ': değer2}, {' anahtar3 ': değer3}, ...]

Ayrıca numaralandırma kullanarak daha fazla pitonik yapabilirsiniz:

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

Bu "-v", dizideki tüm örnekleri kaldırır sys.argvve hiçbir örnek bulunmadığında şikayet etmez:

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

Kodu çalışmakta olan şu dosyada görebilirsiniz 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

Bu sadece kullanmak, benim cevaptır iken ve için

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()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.