Удаление словаря в списке по значению

Есть список словарей:

list = [{'id': 123456, 'name': 'a'}, 
        {'id': 456123, 'name': 'a'}, 
        {'id': 789465, 'name': 'a'}]

Нужно из него удалить словарь со значением 'id' = 123456 Делал так:

for i, elem in enumerate(list):
    if list[i]['id'] != 123456:
        del list[i]

Но так не получается, так как после удаления i становится не актуальной и итерация не срабатывеает.

Подскажите, пожалуйста, как можно это сделать?


Ответы (3 шт):

Автор решения: insolor

Лучше не менять исходный список, а создавать новый:

lis1 = [{'id': 123456, 'name': 'a'}, 
        {'id': 456123, 'name': 'a'}, 
        {'id': 789465, 'name': 'a'}]

lst2 = []

for elem in lis1:
    if elem['id'] == 123456:
        lst2.append(elem)

# Или одной строкой:
# lst2 = [elem for elem in lst1 if elem['id'] == 123456]

Также добавлю, что не рекомендуется называть переменные именами совпадающими с именами встроенных функций и других объектов (list, set, dict и т.д.)

→ Ссылка
Автор решения: gil9red

Проблема в том, что перебор вы делается по возрастающей, но при удалении новые индексы будут неактуальные, т.к. верхняя граница уменьшилась.

Решением будет удаление от конца к началу:

items = [
    {'id': 123456, 'name': 'a'},
    {'id': 456123, 'name': 'a'},
    {'id': 789465, 'name': 'a'}
]

for i in reversed(range(len(items))):
    if items[i]['id'] == 123456:
        del items[i]

print(items)
# [{'id': 456123, 'name': 'a'}, {'id': 789465, 'name': 'a'}]

Тот же цикл, но без reversed:

for i in range(len(items) - 1, -1, -1):
    if items[i]['id'] == 123456:
        del items[i]
→ Ссылка
Автор решения: vadim vaduxa

бывает условие слишком сложно для записи в одну стоку, тогда удобно использовать filter, если func вернет True - значение добавится, иначе нет

lis1 = [{'id': 123456, 'name': 'a'},
        {'id': 456123, 'name': 'a'},
        {'id': 789465, 'name': 'a'}]

def func(x):
    if x['id'] == 123456:
        return False
    elif x['id'] % 19:
        if x['name'] == 'a':
            return True
        elif x['name'] == 'b':
            return False
    return True

lis1 = list(filter(func, lis1))
→ Ссылка