Python: удалить словарь из списка

Если у меня есть список словарей, скажите:

[{'id': 1, 'name': 'paul'}, {'id': 2, 'name': 'john'}] 

и я хотел бы удалить словарь с id 2 (или именем john), что является наиболее эффективным способом сделать это программно (то есть, я не знаю индекс записи в списке, чтобы он нельзя просто выскочить).

  • Использование нескольких ключевых слов в xattr через _kMDItemUserTags или kMDItemOMUserTags
  • Отобразить свободный текст между полями Django Form
  • пользовательский отчет через python odoo 9
  • Когда обновляются файлы .pyc?
  • Лучший способ структурирования приложения tkinter
  • Тройное наследование вызывает конфликт метакласса ... Иногда
  • Анализ XML-кода из URL-адреса в объект python
  • Python Pandas - Как сгладить иерархический индекс в столбцах
  • 7 Solutions collect form web for “Python: удалить словарь из списка”

     thelist[:] = [d for d in thelist if d.get('id') != 2] 

    Редактирование : поскольку некоторые сомнения были высказаны в комментарии о производительности этого кода (некоторые из них основаны на непонимании характеристик производительности Python, некоторые из которых полагают, что за пределами указанных спецификаций в списке есть ровно один dict, со значением 2 для ключа ' id '), я хочу предложить заверения в этом вопросе.

    На старом Linux-поле, измеряющем этот код:

     $ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(99)]; import random" "thelist=list(lod); random.shuffle(thelist); thelist[:] = [d for d in thelist if d.get('id') != 2]" 10000 loops, best of 3: 82.3 usec per loop 

    из которых около 57 микросекунд для random.shuffle (необходимо для того, чтобы удалить элемент не ВСЕГДА на том же месте 😉 и 0,65 мкс для начальной копии (кто бы ни беспокоился о влиянии производительности мелких копий списков Python очевидно, чтобы обедать ;-), чтобы избежать изменения исходного списка в цикле (так что каждая нога цикла имеет что-то удалить ;-).

    Когда известно, что есть только один элемент для удаления, его можно найти и удалить еще более оперативно:

     $ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(99)]; import random" "thelist=list(lod); random.shuffle(thelist); where=(i for i,d in enumerate(thelist) if d.get('id')==2).next(); del thelist[where]" 10000 loops, best of 3: 72.8 usec per loop 

    (используйте next встроенный, а не метод .next если вы на Python 2.6 или лучше, конечно), но этот код разрушается, если число dicts, удовлетворяющих условию удаления, не является одним. Обобщая это, мы имеем:

     $ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*3; import random" "thelist=list(lod); where=[i for i,d in enumerate(thelist) if d.get('id')==2]; where.reverse()" "for i in where: del thelist[i]" 10000 loops, best of 3: 23.7 usec per loop 

    где перетасовка может быть удалена, поскольку, как мы знаем, уже есть три равных диктата для удаления. И список, неизменный, тарифы хорошо:

     $ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*3; import random" "thelist=list(lod); thelist[:] = [d for d in thelist if d.get('id') != 2]" 10000 loops, best of 3: 23.8 usec per loop 

    полностью шею и шею, и даже удалить 3 элемента из 99. С более длинными списками и большим количеством повторений это, конечно, еще больше:

     $ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*133; import random" "thelist=list(lod); where=[i for i,d in enumerate(thelist) if d.get('id')==2]; where.reverse()" "for i in where: del thelist[i]" 1000 loops, best of 3: 1.11 msec per loop $ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*133; import random" "thelist=list(lod); thelist[:] = [d for d in thelist if d.get('id') != 2]" 1000 loops, best of 3: 998 usec per loop 

    В целом, очевидно, не стоит развертывать тонкость создания и изменения списка индексов для удаления, а также совершенно простого и очевидного понимания списка, чтобы, возможно, получить 100 наносекунд в одном маленьком случае – и потерять 113 микросекунд в более крупном ;-). Избежать или критиковать простые, простые и идеально подходящие для исполнения решения (например, понимание списков для этого общего класса «удалить некоторые предметы из списка») – особенно неприятный пример известного тезиса Кнута и Хора, что «преждевременная оптимизация корень всего зла в программировании "! -)

    Это не совсем anwser (как я думаю, у вас уже есть некоторые неплохие из них), но … вы считаете, что у вас есть словарь <id>:<name> вместо списка словарей?

    Вот способ сделать это с пониманием списка (если вы назовете свой список «foo»):

     [x for x in foo if not (2 == x.get('id'))] 

    Замените 'john' == x.get('name') или что угодно, если необходимо.

    filter также работает:

    foo.filter(lambda x: x.get('id')!=2, foo)

    И если вы хотите генератор, вы можете использовать itertools:

    itertools.ifilter(lambda x: x.get('id')!=2, foo)

    Однако, как и в случае с Python 3, filter все равно вернет итератор, поэтому понимание списка действительно лучший выбор, как предложил Алекс.

    list.pop () – хороший выбор:

     >>> a = [{'id': 1, 'name': 'paul'}, ... {'id': 2, 'name': 'john'}] >>> a.pop(1) {'id': 2, 'name': 'john'} >>> a [{'id': 1, 'name': 'paul'}] 

    Вы можете разработать другие способы отслеживания, которые вы хотите устранить, если он разрешает целое число. Вот один из способов:

     >>> a = [{'id': 1, 'name': 'paul'}, ... {'id': 2, 'name': 'john'}] >>> for i in reversed(range(len(a))): ... if a[i].get('id') == 2: ... a.pop(i) ... {'id': 2, 'name': 'john'} >>> a [{'id': 1, 'name': 'paul'}] 

    Другая возможность – использовать del:

     [{'id': 1, 'name': 'paul'}] >>> a = [{'id': 1, 'name': 'paul'}, ... {'id': 2, 'name': 'john'}] >>> a [{'id': 1, 'name': 'paul'}, {'id': 2, 'name': 'john'}] >>> del a[1] >>> a [{'id': 1, 'name': 'paul'}] 
     # assume ls contains your list for i in range(len(ls)): if ls[i]['id'] == 2: del ls[i] break 

    Вероятно, будет быстрее, чем методы понимания списка в среднем, потому что он не пересекает весь список, если он находит этот предмет на ранней стадии.

    Вы можете попробовать что-то в следующих строках:

     def destructively_remove_if(predicate, list): for k in xrange(len(list)): if predicate(list[k]): del list[k] break return list list = [ { 'id': 1, 'name': 'John' }, { 'id': 2, 'name': 'Karl' }, { 'id': 3, 'name': 'Desdemona' } ] print "Before:", list destructively_remove_if(lambda p: p["id"] == 2, list) print "After:", list 

    Если вы не создадите что-то похожее на индекс над вашими данными, я не думаю, что вы можете сделать лучше, чем выполнять «сканирование таблицы грубой силы» по всему списку. Если ваши данные отсортированы с помощью ключа, который вы используете, вы можете использовать модуль bisect, чтобы найти объект, который вы ищете, несколько быстрее.

    Вы можете попробовать следующее:

     a = [{'id': 1, 'name': 'paul'}, {'id': 2, 'name': 'john'}] for e in range(len(a) - 1, -1, -1): if a[e]['id'] == 2: a.pop(e) 

    Если вы не можете поп с самого начала – поп с конца, это не испортит цикл for.

    Interesting Posts

    Как вызвать внешнюю программу на python и получить код вывода и возврата?

    Импортировать приложение в проект django

    Как получить столбец по номеру в Пандах?

    Python – извлечение файлов из большого (6GB +) zip-файла

    Шифрование файла с помощью RSA в Python

    приостановить / возобновить скрипт python в середине

    AttributeError: экземпляр StringIO не имеет атрибута 'fileno'

    Как определить, является ли ввод пользователем допустимым шестнадцатеричным числом?

    Может ли соскабливаться на этой странице, которая активно пересчитывается?

    Оценка значений серии pandas с помощью логических выражений и if-операторов

    кто может сказать мне, что можно назвать встроенными функциями в следующем коде

    Как обслуживать любой тип файла с помощью Python BaseHTTPRequestHandler

    Python. Селен. Как подождать нового окна?

    Проблема в динамическом добавлении методов в класс Python (например, django-tables2 «Таблица»)

    Браузер изображений Django Ckeditor не находит изображения

    Python - лучший язык программирования в мире.