* є оператором "splat": він приймає список як вхідний і розширює його на фактичні позиційні аргументи у виклику функції.
Так що якщо uniqueCrossTabsбуло [ [ 1, 2 ], [ 3, 4 ] ], то itertools.chain(*uniqueCrossTabs)те саме, що говоритиitertools.chain([ 1, 2 ], [ 3, 4 ])
Це, очевидно, відрізняється від проходження просто uniqueCrossTabs. У вашому випадку у вас є список списків, які ви хочете вирівняти; що itertools.chain()полягає в тому, щоб повернути ітератор за конкатенацію всіх позиційних аргументів, які ви передаєте йому, де кожен позиційний аргумент є ітерабельним самостійно.
Іншими словами, ви хочете передати кожен список uniqueCrossTabsяк аргумент chain(), який з'єднає їх разом, але у вас немає списків в окремих змінних, тому ви використовуєте *оператор для розширення списку списків на кілька аргументів списку.
Як в коментарях зазначила Йочен Рітцель, chain.from_iterable()вона більше підходить для цієї операції, оскільки передбачає, що для початку слід здійснити єдиний ітерабел ітерабелів. Ваш код потім стає просто:
uniqueCrossTabs = list(itertools.chain.from_iterable(uniqueCrossTabs))