*
è l'operatore "splat": prende un elenco come input e lo espande in argomenti posizionali effettivi nella chiamata di funzione.
Quindi, se lo uniqueCrossTabs
era [ [ 1, 2 ], [ 3, 4 ] ]
, allora itertools.chain(*uniqueCrossTabs)
è come direitertools.chain([ 1, 2 ], [ 3, 4 ])
Questo è ovviamente diverso dal semplice passaggio uniqueCrossTabs
. Nel tuo caso, hai un elenco di elenchi che desideri appiattire; quello che itertools.chain()
fa è restituire un iteratore sulla concatenazione di tutti gli argomenti posizionali che gli passi, dove ogni argomento posizionale è iterabile di per sé.
In altre parole, vuoi passare ogni elenco uniqueCrossTabs
come argomento a chain()
, che li concatenerà insieme, ma non hai gli elenchi in variabili separate, quindi usi l' *
operatore per espandere l'elenco di elenchi in diversi argomenti di elenco.
Come Jochen Ritzel ha sottolineato nei commenti, chain.from_iterable()
è più adatto per questa operazione, in quanto presuppone un singolo iterabile per cominciare. Il tuo codice diventa quindi semplicemente:
uniqueCrossTabs = list(itertools.chain.from_iterable(uniqueCrossTabs))