2013-03-02 25 views
7

Ho bisogno di questo comportamento, ma preferisco avere una lista in diminuzione piuttosto che crescente. L'ordine di sequenza è importante per questa operazione.Append to List while Iterating

for item in mylist: 
    if is_item_mature(item): 
     ## Process him 
    else: 
     ## Check again later 
     mylist.append(item) 

ma preferirei che fosse più simile. Questo si comporta come penso? Qualche modo migliore?

while mylist: 
    item = list.pop(0) 
    if is_item_mature(item): 
     ##Process 
    else: 
     mylist.append(item) 
+1

'list' non è una buona scelta del nome della variabile. –

+0

Sì, sembra che si comporti come credi. Ma funziona come ti aspettavi che funzionasse? –

+0

Tutto sembra bene, solo il singhiozzo era un deadlock su alcuni degli ultimi elementi (parte del mio set di dati era in errore). Il debugger ha catturato la coda che gli insegue la coda. – user2097818

risposta

6

L'unico problema che vedo con il suo approccio è una lista crescente che a seconda del vostro uso può mangiare il vostro memoria

vorrei piuttosto suggerire di utilizzare un Queue. La coda è progettata e abbastanza flessibile per gestire sia la produzione finale che il consumo

from Queue import Queue 
q = Queue() #You can also specify the maximum size of the Queue here 
# Assume your Queue was filled 
while not q.empty(): 
    # It won;t block if there are no items to pop 
    item = q.get(block = False) 
    if is_item_mature(item): 
     #process 
    else: 
     #In case your Queue has a maxsize, consider making it non blocking 
     q.put(item) 
+0

+1 una coda è la strada da percorrere! buon esempio anche –

+0

Penso che mi piaccia anche questo. Il mio ciclo di elaborazione è un po 'grezzo al momento, e il sequenziamento rigoroso mi salva da qualche codice in più per il momento. – user2097818

+0

'Queue.Queue' è per il multithreading. Se non ti serve, usa semplicemente 'collections.deque', che viene usato internamente da Queue. – koddo

5

È possibile aggiungere in modo sicuro elementi all'elenco, e l'iterazione comprende i punti:

>>> lst = range(5) 
>>> for i in lst: 
...  print i 
...  if i < 3: 
...   lst.append(i + 10) 
... 
0 
1 
2 
3 
4 
10 
11 
12 

Tuttavia, se si preferisce una lista lineare, quindi il ciclo while è perfettamente adatto per le vostre esigenze .

+0

Come sai che questo è sicuro e funziona così? È documentato da qualche parte? Ho cercato di trovare qualche prova a lungo per questo ... –

+0

@StefanPochmann: Come faccio a saperlo? Esperienza e conoscenza dell'elenco e lista dei dettagli di implementazione dell'iteratore. Non è esplicitamente documentato. –

+0

@StefanPochmann: l'elenco iteratore restituito da 'iter (elenco)' memorizza una posizione corrente (un numero intero) e un riferimento all'elenco. Ogni volta che si ottiene l'elemento successivo, la posizione corrente viene confrontata con la dimensione dell'elenco corrente e, se è più piccola, l'elemento nella posizione corrente viene recuperato dall'elenco, la posizione viene incrementata e l'elemento recuperato viene restituito. –