Domanda

La comprensione della lista per me sembra essere come il blocco opaco di granito che le espressioni regolari sono per me. Ho bisogno di puntatori.

Dire, ho un elenco 2D:

li = [[0,1,2],[3,4,5],[6,7,8]]

Vorrei unire questo in un lungo elenco

li2 = [0,1,2,3,4,5,6,7,8]

o in una stringa con separatori:

s = "0,1,2,3,4,5,6,7,8"

Davvero, vorrei sapere come fare entrambe le cose.

È stato utile?

Soluzione

In questo modo:

[ item for innerlist in outerlist for item in innerlist ]

Trasformandolo direttamente in una stringa con separatori:

','.join(str(item) for innerlist in outerlist for item in innerlist)

Sì, l'ordine di "per elenco interno in elenco esterno" e "per elemento in elenco interno" è corretto. Anche se il "corpo" del loop è all'inizio di listcomp, l'ordine dei loop nidificati (e le clausole 'if') è sempre lo stesso di quando si scriverebbe il loop out:

for innerlist in outerlist:
    for item in innerlist:
        ...

Altri suggerimenti

Prova quello:

li=[[0,1,2],[3,4,5],[6,7,8]]
li2 = [ y for x in li for y in x]

Puoi leggerlo in questo modo:
Dammi la lista di tutti voi.
Gli y vengono dalla xs.
Le x vengono da li.

Per mappare quello in una stringa:

','.join(map(str,li2))

Ci sono un paio di scelte. Innanzitutto, puoi semplicemente creare un nuovo elenco e aggiungere il contenuto di ciascun elenco ad esso:

li2 = []
for sublist in li:
    li2.extend(sublist)

In alternativa, puoi usare la funzione chain del modulo itertools , che produce un iterabile contenente tutti gli elementi in più iterabili:

import itertools
li2 = list(itertools.chain(*li))

Se segui questo approccio, puoi produrre la stringa senza creare un elenco intermedio:

s = ",".join(itertools.chain(*li))

Il mio preferito, e il più breve, è questo:

li2 = sum(li, [])

e

s = ','.join(li2)

EDIT: usa sum invece di riduci , (grazie Thomas Wouters !)

Per renderlo un elenco appiattito utilizzare:

  1. http://code.activestate.com/recipes/121294/
  2. http://code.activestate.com/recipes/363051/

Quindi, join per renderlo una stringa.

Per il secondo, esiste un metodo stringa incorporato per farlo:

>>> print ','.join(str(x) for x in li2)
"0,1,2,3,4,5,6,7,8"

Per il primo, è possibile utilizzare join all'interno di un elenco di comprensione:

>>> print ",".join([",".join(str(x) for x in li])
"0,1,2,3,4,5,6,7,8"

Ma è più facile usare itertools.flatten:

>>> import itertools
>>> print itertools.flatten(li)
[0,1,2,3,4,5,6,7,8]
>>> print ",".join(str(x) for x in itertools.flatten(li))
"0,1,2,3,4,5,6,7,8"

NB: itertools è un modulo che ti aiuta a gestire compiti comuni con iteratori come elenco, tuple o stringa ... È utile perché non memorizza una copia della struttura su cui stai lavorando ma elabora gli elementi uno per uno.

EDIT: divertente, sto imparando un sacco di modi per farlo. Chi ha detto che c'era solo un buon modo per farlo?

Esistono molti modi per risolvere questo problema. Mi piacciono gli strumenti di Numpy perché normalmente sono già importati in tutto ciò che faccio. Tuttavia, se non stai usando Numpy per nient'altro questo probabilmente non è un buon metodo.

import numpy
li = [[0,1,2],[3,4,5],[6,7,8]]
li2=li[0] #first element of array to merge
i=1 
while i<len(li):
    li2=numpy.concatenate((li2,li[i]))
    i+=1
print li2

Questo verrebbe stampato [0 1 2 3 4 5 6 7 8] e quindi puoi anche convertirlo nella tua stringa.

import itertools
itertools.flatten( li )
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top