*
est l'opérateur "splat": il prend une liste comme entrée et l'étend en arguments positionnels réels dans l'appel de fonction.
Donc si uniqueCrossTabs
c'était le cas [ [ 1, 2 ], [ 3, 4 ] ]
, alors itertools.chain(*uniqueCrossTabs)
c'est la même chose que de direitertools.chain([ 1, 2 ], [ 3, 4 ])
C'est évidemment différent du passage juste uniqueCrossTabs
. Dans votre cas, vous avez une liste de listes que vous souhaitez aplatir; ce qui itertools.chain()
fait est de retourner un itérateur sur la concaténation de tous les arguments positionnels que vous lui passez, où chaque argument positionnel est itérable à part entière.
En d'autres termes, vous voulez passer chaque liste en uniqueCrossTabs
tant qu'argument à chain()
, ce qui les enchaînera, mais vous n'avez pas les listes dans des variables séparées, vous utilisez donc le*
opérateur pour développer la liste des listes en plusieurs arguments de liste.
Comme Jochen Ritzel l'a souligné dans les commentaires, chain.from_iterable()
est mieux adapté pour cette opération, car elle suppose un seul itérable d'itérables pour commencer. Votre code devient alors simplement:
uniqueCrossTabs = list(itertools.chain.from_iterable(uniqueCrossTabs))