thelist[:] = [d for d in thelist if d.get('id') != 2]
Edit: некоторые сомнения были высказаны в комментарии о выполнении этого кода (некоторые на основе непонимания характеристик Python, некоторые на предположении, за данной спецификации, что существует ровно один ДИКТ в список со значением 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
где перетасовки могут быть удалены, потому что есть уже три эквидистантно dicts, чтобы удалить, как мы знаем. И listcomp, без изменений, тарифы также:
$ 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 микросекунд в более крупном ;-). Избежать или критиковать простые, простые и идеально подходящие для исполнения решения (например, понимание списков для этого общего класса «удалить некоторые предметы из списка») - особенно неприятный пример известного тезиса Кнута и Хора, что «преждевременная оптимизация корень всех зол в программировании "-)
Две причины, почему это плохо: он копирует весь список, и он проходит весь список, даже если словарь, содержащий id 2, является самым первым элементом. – Imagist
@imagist, это тем не менее быстро - ИЗМЕРИТЕ его, ради всего святого, не просто ПРИНИМАЙТЕ, что вы знаете, о чем говорите, особенно. когда вы, очевидно, не делаете :-), * ESPECIALLY *, когда элемент для удаления является первым (он избегает перемещения каждого другого элемента). И в исходном вопросе нет указаний на то, что каждый dict в списке ДОЛЖЕН всегда иметь другое значение, соответствующее «id». –
Хмммм. Неплохо. Существует два подхода: создать новый список с некоторыми элементами, отфильтрованными или изменить существующий список, чтобы удалить некоторые элементы. Это только прежний подход. И что касается этого, нечего сказать, что словарь с id = 2 не будет отображаться более одного раза в списке. Это список - нет гарантии уникальности. И ОП не предлагал этого ограничения. – hughdbrown