Python kullanarak bir diziden belirli bir öğeyi kaldırma


138

Bir diziden belirli bir öğeyi kaldıran bir şey yazmak istiyorum. forİçeriğe uyan öğeyi bulmak için dizi döngü gerekir biliyorum .

Diyelim ki bir dizi e-postam var ve bazı e-posta dizesiyle eşleşen öğeden kurtulmak istiyorum.

Aslında diğer diziler için de aynı dizini kullanmak gerekir çünkü for döngüsü yapısını kullanmak istiyorum.

İşte sahip olduğum kod:

for index, item in emails:
    if emails[index] == 'something@something.com':
         emails.pop(index)
         otherarray.pop(index)

6
Arıyorsunuz list.remove(x)?
Jacob

tam olarak değil. i endeksi yeniden kullanabilirsiniz böylece for döngüsü kullanmak istiyorum
locoboy

4
Tekrarlanırken listeyi değiştirmemelisiniz.
Jacob

bunu neden yapmamalıyım? ayrıca benim için çalışmıyor.
locoboy

Yanıtlar:


200

Diziyi yinelemenize gerek yoktur. Sadece:

>>> x = ['ala@ala.com', 'bala@bala.com']
>>> x
['ala@ala.com', 'bala@bala.com']
>>> x.remove('ala@ala.com')
>>> x
['bala@bala.com']

Bu, dizeyle eşleşen ilk olayı kaldıracaktır.

DÜZENLEME: Düzenlemenizden sonra, yine de tekrarlamanız gerekmez. Sadece yap:

index = initial_list.index(item1)
del initial_list[index]
del other_list[index]

1
yukarıya bakın ben aynı dizini yeniden kullanmak için for döngüsü kullanmak istiyorum
locoboy

Cevabımı düzenledi. Hala döngüye gerek yok.
Bogdan

1
İlk olarak öğenin initial_list'te olup olmadığını nasıl kontrol edersiniz? Var olmayan bir durum olabilir ve onu kaldırmak zorunda kalmazsınız.
locoboy

17

Kullanmak filter()ve lambdaistenmeyen değerleri kaldırmak için düzgün ve kısa bir yöntem sağlar:

newEmails = list(filter(lambda x : x != 'something@something.com', emails))

Bu, e-postaları değiştirmez. Yalnızca anonim işlevinin True döndürdüğü öğeleri içeren yeni liste newEmails'i oluşturur.


5

For loop kullanımında dizine ihtiyacınız varsa for döngünüz doğru değil:

for index, item in enumerate(emails):
    # whatever (but you can't remove element while iterating)

Sizin durumunuzda, Bogdan çözümü iyi, ancak veri yapısı seçiminiz o kadar iyi değil. Bu iki listenin birinden diğerinin verileri ile aynı dizindeki verilerin saklanması zorunludur.

Bir tupple listesi (e-posta, diğer veriler) daha iyi veya anahtar olarak e-posta ile bir diksiyon olabilir.


4

Bunu yapmanın akılcı yolu kullanmak zip()ve bir Liste Anlama / Jeneratör İfadesi:

filtered = (
    (email, other) 
        for email, other in zip(emails, other_list) 
            if email == 'something@something.com')

new_emails, new_other_list = zip(*filtered)

Ayrıca, array.array()veya kullanmıyorsanız numpy.array(), büyük olasılıkla []veya list()Dizileri değil Listeler veren veya kullanıyorsunuzdur . Aynı şey değil.


1
Hiçbiri, bu "Bogdan" çok, çok daha temiz @ cevabı ile karşılaştırıldığında nasıl emin.
Jordan Lapp

Dizilerin listelerle aynı olmadığına dikkat çektiğiniz için teşekkür ederiz. Seçilen cevap 2.7'deki dizilerde çalışmaz.
EL_DON

2

Yinelenen eşleşmelerle de ilgilenen bu soruna alternatif bir çözüm var.

Eşit uzunlukta 2 liste ile başlıyoruz: emails, otherarray. Amaç her dizin için her iki listedeki öğeleri kaldırmaktır inerede emails[i] == 'something@something.com'.

Bu, bir liste kavrayışı kullanılarak ve daha sonra şu şekilde bölünerek elde edilebilir zip:

emails = ['abc@def.com', 'something@something.com', 'ghi@jkl.com']
otherarray = ['some', 'other', 'details']

from operator import itemgetter

res = [(i, j) for i, j in zip(emails, otherarray) if i!= 'something@something.com']
emails, otherarray = map(list, map(itemgetter(0, 1), zip(*res)))

print(emails)      # ['abc@def.com', 'ghi@jkl.com']
print(otherarray)  # ['some', 'details']
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.