thelist[:] = [d for d in thelist if d.get('id') != 2]
Edit: come alcuni dubbi sono stati espressi in un commento circa le prestazioni di questo codice (alcuni basati su fraintendendo le caratteristiche di prestazione di Python, un po 'nell'assumere al di là delle specifiche, dato che non v'è esattamente un dict nel lista con un valore di 2 per la chiave 'id'), vorrei offrire rassicurazione su questo punto.
Su una vecchia scatola di Linux, la misurazione di questo codice:
$ 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
di cui circa 57 microsecondi per la random.shuffle (necessario per garantire che l'elemento da rimuovere non è sempre nello stesso punto ;-) e 0,65 microsecondi per la copia iniziale (chi si preoccupa dell'impatto sulle prestazioni delle copie superficiali delle liste Python è ovviamente fuori a pranzo ;-), necessario per evitare di alterare l'elenco originale nel ciclo (quindi ogni parte del ciclo ha qualcosa da Elimina;-).
Quando si sa che c'è esattamente un elemento da rimuovere, è possibile individuare e rimuovere ancora più rapidamente:
$ 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
(utilizzare il comando incorporato next
piuttosto che il metodo .next
se siete su Python 2.6 o superiore, ovviamente) - ma questo codice si rompe se il numero di dict che soddisfano la condizione di rimozione non è esattamente uno. Generalizzando questo, abbiamo:
$ 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
dove il rimescolamento può essere rimosso perché ci sono già tre dicts equidistanti da rimuovere, come sappiamo. E il listcomp, invariati, tariffe e:
$ 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
totalmente testa a testa, con anche solo 3 elementi di 99 da rimuovere. Con gli elenchi più lunghi e più ripetizioni, questo vale ancora di più, naturalmente:
$ 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
Tutto sommato, non è, ovviamente, vale la distribuzione la sottigliezza di fare e invertire l'elenco degli indici di rimuovere, contro la lista perfettamente semplice ed evidente comprensione, per guadagnare forse 100 nanosecondi in un piccolo caso - e perdere 113 microsecondi in uno più grande ;-). Evitare o criticare soluzioni semplici, dirette e perfettamente adeguate alle prestazioni (come la comprensione delle liste per questa classe generale di problemi "rimuovere alcuni elementi da una lista") è un esempio particolarmente sgradevole della famosa tesi di Knuth e Hoare secondo cui "l'ottimizzazione prematura è la radice di tutti i mali in programmazione "-)
Due motivi per cui questo non funziona: copia l'intera lista e attraversa l'intera lista anche se il dizionario contenente id 2 è il primo elemento. – Imagist
@imagist, è comunque il più veloce - MISURARLO, per carità, non solo ASSUMI di sapere di cosa stai parlando, esp. quando ovviamente non lo fai ;-), * SOPRATTUTTO * quando l'elemento da rimuovere è il primo (evita di spostare ogni altro oggetto). E non c'è alcuna indicazione nella domanda originale che ogni dict nella lista DEVE sempre avere un valore diverso corrispondente a 'id'. –
Hmmmm. Non male. Ci sono due approcci: creare un nuovo elenco con alcuni elementi filtrati o modificare l'elenco esistente per rimuovere alcuni elementi. Questo è solo il primo approccio. E per quanto riguarda ciò, non c'è nulla da dire che un dizionario con id = 2 non apparirà più di una volta nella lista. È una lista - non c'è garanzia di unicità. E l'OP non ha suggerito questa limitazione. – hughdbrown