Asked By – Ramy
I’m using itertools.chain to “flatten” a list of lists in this fashion:
uniqueCrossTabs = list(itertools.chain(*uniqueCrossTabs))
how is this different than saying:
uniqueCrossTabs = list(itertools.chain(uniqueCrossTabs))
Now we will see solution for issue: Asterisk in function call [duplicate]
* is the “splat” operator: It takes an iterable like a list as input, and expands it into actual positional arguments in the function call.
[[1, 2], [3, 4]], then
itertools.chain(*uniqueCrossTabs) is the same as saying
itertools.chain([1, 2], [3, 4])
This is obviously different from passing in just
uniqueCrossTabs. In your case, you have a list of lists that you wish to flatten; what
itertools.chain() does is return an iterator over the concatenation of all the positional arguments you pass to it, where each positional argument is iterable in its own right.
In other words, you want to pass each list in
uniqueCrossTabs as an argument to
chain(), which will chain them together, but you don’t have the lists in separate variables, so you use the
* operator to expand the list of lists into several list arguments.
chain.from_iterable() is better-suited for this operation, as it assumes a single iterable of iterables to begin with. Your code then becomes simply:
uniqueCrossTabs = list(itertools.chain.from_iterable(uniqueCrossTabs))