2010-06-10 5 views
5

Ho un set di dati di eventi (tweets specifici) che sto cercando di bin/discretizzare. Il seguente codice sembra funzionare bene finora (assumendo 100 cassonetti):Scanalatura in fasce orarie - Esiste un modo migliore rispetto all'utilizzo della lista comp?

HOUR = timedelta(hours=1) 
start = datetime.datetime(2009,01,01) 
z = [dt + x*HOUR for x in xrange(1, 100)] 

Ma poi, mi sono imbattuto in questa linea fatidica a docs pitone 'Questo rende possibile un idioma per il clustering di una serie di dati in gruppi n-length utilizzando zip(*[iter(s)]*n) '. L'idioma di zip funziona davvero - ma non riesco a capire come (qual è l'operatore * ad esempio?). Come potrei usare per rendere il mio codice più carino? Immagino che questo significhi che dovrei fare un generatore/iterable per il tempo che yields il tempo in graduazioni di un'ora?

+1

Vedere [sezione "Chiamate" nei documenti python] (http://docs.python.org/reference/expressions.html#calls) per la stella. – Marian

risposta

5

cercherò di spiegare zip(*[iter(s)]*n) in termini di un esempio più semplice:

immaginate di avere la lista s = [1, 2, 3, 4, 5, 6]

iter(s) ti dà un oggetto listiterator che produrrà il prossimo numero da s ogni volta che si chiede per un elemento.

[iter(s)] * n ti dà la lista con iter(s) in esso n volte per esempio [iter(s)] * 2 = [<listiterator object>, <listiterator object>] - la chiave qui è che questi sono 2 riferimenti allo stesso oggetto iteratore, non a 2 oggetti iteratori distinti.

zip prende un numero di sequenze e restituisce una lista di tuple dove ogni tupla contiene l'elemento esimo da ciascuna delle sequenze. per esempio. zip([1,2], [3,4], [5,6]) = [(1, 3, 5), (2, 4, 6)] dove (1, 3, 5) sono i primi elementi dei parametri passati a zip e (2, 4, 6) sono i secondi elementi dai parametri passati a zip.

Il * davanti *[iter(s)]*n converte il [iter(s)]*n dall'essere un elenco in essere diversi parametri passati a zip. quindi se n è 2 otteniamo zip(<listiterator object>, <listiterator object>)

zip sarà richiedere l'elemento successivo da ciascuno dei suoi parametri, ma perché questi sono entrambi riferimenti allo stesso iteratore Ciò comporterà (1, 2), lo fa lo stesso nuovamente conseguente (3, 4) e nuovamente risultante in (5, 6) e quindi non ci sono più elementi quindi si ferma. Da qui il risultato [(1, 2), (3, 4), (5, 6)]. Questo è il raggruppamento di una serie di dati in gruppi di lunghezza n come menzionato.

+0

+1 per l'eccellente spiegazione del pitone – Anoyz

5

L'espressione dalla documentazione si presenta così:

zip(*[iter(s)]*n) 

Ciò equivale a:

it = iter(s) 
zip(*[it, it, ..., it]) # n times 

Il [...]*n ripete la lista n volte, e questo si traduce in un elenco che contiene n riferimenti allo stesso iteratore.

Questo è ancora pari a:

it = iter(s) 
zip(it, it, ..., it) # turning a list into positional parameters 

Il * prima lista trasforma gli elementi della lista in parametri posizionali della chiamata di funzione.

Ora, quando viene chiamato zip, inizia da sinistra a destra per chiamare gli iteratori per ottenere elementi che devono essere raggruppati. Poiché tutti i parametri si riferiscono allo stesso iteratore, questo produce i primi n elementi della sequenza iniziale. Quindi quel processo continua per il secondo gruppo nell'elenco risultante e così via.

Il risultato è lo stesso come se si fosse costruito l'elenco come questo (valutata da sinistra a destra):

it = iter(s) 
[(it.next(), it.next(), ..., it.next()), (it.next(), it.next(), ..., it.next()), ...] 
+1

Brillante - molte grazie per la spiegazione dettagliata - ha senso ora! – malangi

Problemi correlati