2014-04-16 17 views
11

Quindi, ho un iterable di 3-tuple, generato pigramente. Sto cercando di capire come trasformare questo in 3 iterables, costituiti rispettivamente dal primo, dal secondo e dal terzo elemento delle tuple. Tuttavia, vorrei che questo fosse fatto pigramente.Trasporta con calma una lista in Python

Così, per esempio, vorrei [(1, 2, 3), (4, 5, 6), (7, 8, 9)] per essere trasformato in [1, 4, 7], [2, 5, 8], [3, 6, 9]. (Tranne che desidero iterabili non elenchi.)

L'idioma standard zip(*data) non funziona, poiché l'argomento decompressione espande l'intero iterabile. (È possibile verificare ciò osservando che zip(*((x, x+1, x+2) for x in itertools.count(step=3))) si blocca.)

Il migliore che è venuta in mente finora è il seguente:

def transpose(iterable_of_three_tuples): 
    teed = itertools.tee(iterable_of_three_tuples, 3) 
    return map(lambda e: e[0], teed[0]), map(lambda e: e[1], teed[1]), map(lambda e: e[2], teed[2]) 

Questo sembra funzionare. Ma difficilmente sembra un codice pulito. E fa molto di quello che sembra essere un lavoro non necessario.

+1

'izip' dal modulo' itertools'? –

+0

Dato che si dispone di codice funzionante, è possibile ottenere risultati migliori dalla revisione del codice – wnnmaw

+0

Come si prevede che il nuovo iteratore ottenga, ad esempio, il '7' dalla terza tupla senza consumare l'intero iterabile esterno? Il tuo 'tranpose' si bloccherà anche se lo proverai su un iteratore infinito come' count'. – BrenBarn

risposta

3

Il tuo transpose è praticamente esattamente quello che ti serve.

Con qualsiasi soluzione scelta, è necessario memorizzare i valori non utilizzati (ad esempio, per ottenere il 7, è necessario leggere 1-6 e archiviarli in memoria per quando gli altri iterabili li richiedono). tee fa già esattamente questo tipo di buffering, quindi non è necessario implementarlo da solo.

L'unico altro (minore) è che cosa avrei scritto in modo leggermente diverso, evitando le map e lambda s:

def transpose(iterable_of_three_tuples): 
    teed = itertools.tee(iterable_of_three_tuples, 3) 
    return (e[0] for e in teed[0]), (e[1] for e in teed[1]), (e[2] for e in teed[2]) 
Problemi correlati