thelist[:] = [d for d in thelist if d.get('id') != 2]
Edit: jak pewne wątpliwości zostały wyrażone w komentarzu na temat wykonywania tego kodu (niektóre oparte na nieporozumienie charakterystyk Pythona, niektóre na założeniu poza podanymi specyfikacjami, że istnieje dokładnie jedna dict w lista o wartości 2 dla klucza "id"), chciałbym zaoferować zabezpieczenie w tym punkcie.
na starej Linuksie, pomiar ten kod:
których
$ 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
około 57 mikrosekund dla random.shuffle (potrzebne do zapewnienia, że element do usunięcia nie jest zawsze w tym samym miejscu ;-) i 0,65 mikrosekundy dla początkowej kopii (ktokolwiek martwi się o wydajność płytkich kopii list Pythona jest najwyraźniej na lunch ;-), konieczny do uniknięcia zmiany oryginalnej listy w pętli (więc każda noga pętli ma coś do kasować;-).
Kiedy wiadomo, że istnieje dokładnie jeden element, aby usunąć, to jest możliwe, aby zlokalizować i usunąć go jeszcze bardziej sprawny:
$ 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
(użyj next
wbudowane zamiast metody .next
jeśli jesteś na Python 2.6 lub lepszy, oczywiście) - ale ten kod ulega rozpadowi, jeśli liczba dykt, które spełniają warunek usunięcia, nie jest dokładnie taka sama. Uogólniając to mamy:
$ 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
gdzie tasowanie może zostać usunięty ponieważ istnieją już trzy równo rozmieszczone dicts usunąć, jak wiemy. I listcomp niezmienione opłaty również:
$ 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
całkowicie karku i szyi, a nawet tylko trzy elementy 99 powinny być usunięte. Przy dłuższych list i więcej powtórzeń, to posiada jeszcze przedmiotu:
$ 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
W sumie, to nie jest oczywiście warto wdrażania subtelności tworzenia i cofania listę indeksów do usunięcia vs listy idealnie proste i oczywiste zrozumienie, aby uzyskać 100 nanosekund w jednym małym przypadku - i stracić 113 mikrosekund w większym ;-). Unikanie lub krytykowanie prostych, prostych i perfekcyjnie dostosowanych do wydajności rozwiązań (jak na przykład rozumienie list dla tej ogólnej klasy "usuwania niektórych pozycji z listy") jest szczególnie przykrym przykładem dobrze znanej tezy Knutha i Hoare'a, że "przedwczesna optymalizacja to korzeniem wszelkiego zła w programowaniu "-)
Dwa powody, dla których jest to złe: kopiuje całą listę i przechodzi przez całą listę, nawet jeśli słownik zawierający id 2 jest pierwszym elementem. – Imagist
@imagist, jest jednak najszybszy - ZROBIĆ to, na miłość boską, nie myśl tylko, że wiesz o czym mówisz, szczególnie. kiedy najwyraźniej nie ;-), * SZCZEGÓLNIE * kiedy przedmiot do usunięcia jest pierwszy (unika się przesuwania każdego innego przedmiotu). I nic nie wskazuje na oryginalne pytanie, że każdy dict na liście MUSI zawsze mieć inną wartość odpowiadającą "id". –
Hmmmm. Nie jest zły. Istnieją dwa podejścia: utworzyć nową listę z niektórymi elementami odfiltrowanymi lub zmodyfikować istniejącą listę, aby usunąć niektóre elementy. To tylko pierwsze podejście. I tak daleko, nie ma nic do powiedzenia, że słownik o id = 2 nie pojawi się więcej niż jeden raz na liście. To lista - nie ma gwarancji wyjątkowości. OP nie sugerował tego ograniczenia. – hughdbrown