2012-04-25 18 views
10

In primo luogo, per favore perdonami per il titolo un po 'scadente. Non ero abbastanza sicuro di come parlarne. Se qualcuno potesse suggerire un titolo migliore sarebbe fantastico.Comprensioni elenco Python Splitting loop variable

Sto cercando di scoprire se esiste un modo per dividere il valore di ciascuna iterazione di una comprensione di lista solo una volta, ma usarlo due volte nell'output. Un esempio del problema che sto cercando di risolvere è:

ho la stringa

a = "1;2;4\n3;4;5" 

E vorrei eseguire questo:

>>> [(x.split(";")[1],x.split(";")[2]) for x in a.split("\n") if x.split(",")[1] != 5] 
[('2', '4'), ('4', '5')] 

Senza la necessità di correre diviso per tre volte . Quindi, qualcosa di simile (che è la sintassi, ovviamente, non valida, ma si spera è sufficiente per ottenere il messaggio):

[(x[1],x[2]) for x.split(";") in a.split("\n") if x[1] != 5] 

In questa domanda sono non alla ricerca di modi di fantasia per ottenere il 2 ° e 3 ° colonna della stringa . È solo un modo per fornire un esempio concreto. Ho potuto per il corso per l'esempio l'uso:

[x.split(";")[1:3] for x in a.split("\n")] 

Le possibili soluzioni che ho pensato:

  1. Non utilizzare una list comprehension
  2. Lascia come è
  3. Utilizzare il csv.DictReader , dai il nome alle mie colonne e qualcosa come StringIO per dargli l'input.

Questo è soprattutto qualcosa che sarebbe un bel motivo per essere in grado di utilizzare, piuttosto che un caso specifico quindi è difficile rispondere al "perché vuoi fare questo" o "che cosa è questo per" Kinda domande

Grazie in anticipo :)

UPDATE: Dopo essere stato letto il soluzione qui di seguito sono andato e corse alcuni test di velocità. E ho trovato nei miei test di base che la soluzione fornita era del 35% più veloce rispetto alla soluzione ingenua di cui sopra.

risposta

16

Si potrebbe utilizzare una comprensione lista avvolto intorno ad un generatore di espressione:

[(x[1],x[2]) for x in (x.split(";") for x in a.split("\n")) if x[1] != 5] 
+0

grazie molto cool :) – Nick