Як видалити конкретний елемент з масиву за допомогою python


138

Я хочу написати щось, що видаляє певний елемент з масиву. Я знаю, що мені потрібно провести forцикл через масив, щоб знайти елемент, який відповідає вмісту.

Скажімо, у мене є масив електронних листів, і я хочу позбутися елемента, який відповідає деякому рядку електронної пошти.

Я фактично хотів би використовувати структуру для циклу, тому що мені потрібно використовувати той самий індекс і для інших масивів.

Ось код, який у мене є:

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

6
Шукаєте list.remove(x)?
Яків

не зовсім. Я хотів би використовувати цикл for, щоб я міг повторно використовувати індекс
locoboy

4
Ви не повинні змінювати список під час ітерації над ним.
Яків

чому я не повинен цього робити? також це не працює для мене.
locoboy

5
Подивіться на це: Не
Яків

Відповіді:


200

Вам не потрібно повторювати масив. Просто:

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

Це видалить перше виникнення, яке відповідає рядку.

РЕДАКТУВАННЯ: Після редагування вам більше не потрібно повторювати. Просто зробіть:

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

1
дивіться вище, я хотів би використати цикл для повторного використання того ж індексу
locoboy

Відредагував мою відповідь. Ще немає потреби в циклі.
Богдан

1
Як спочатку перевірити, чи існує елемент у початковому списку? Може бути випадок, коли його не існує, і вам не доведеться його видаляти.
locoboy

17

Використання filter()та lambdaзабезпечить акуратний та лаконічний метод видалення небажаних значень:

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

Це не змінює електронні листи. Він створює новий список newEmails, що містить лише елементи, для яких анонімна функція повернула True.


5

Ваш для циклу неправильний, якщо вам потрібен індекс для використання циклу for:

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

У вашому випадку рішення Богдана нормально, але вибір вашої структури даних не дуже вдалий. Дотримуватися цих двох списків з даними одного, пов'язаного з даними з іншого за тим самим індексом, незграбно.

Перелік tupple (електронна пошта, інші дані) може бути кращим, або диктант із електронною поштою як ключовим.


4

Єдиний спосіб зробити це - використання zip()та розуміння списку / генераторне вираження:

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

new_emails, new_other_list = zip(*filtered)

Крім того, якщо ви не використовуєте array.array()або numpy.array(), швидше за все, ви використовуєте []або list(), які дають вам списки, а не масиви. Не те саме.


1
Ніхто не впевнений, наскільки це "здорово" порівняно з відповіддю @ Богдана, яка набагато чистіше.
Йордан Лапп

Дякуємо, що вказали, що масиви не такі, як списки. Вибрана відповідь не працює для масивів у 2.7.
EL_DON

2

Існує альтернативне рішення цієї проблеми, яке також стосується дублікатів відповідностей.

Почнемо з 2 списків однакової довжини: emails, otherarray. Мета - видалити елементи з обох списків для кожного індексу, iдеemails[i] == 'something@something.com' .

Це можна досягти, використовуючи розуміння списку, а потім розділити за допомогою 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']
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.