Collapse the result of the cartesian product
<p>To calculate cartesian product with python is very simple. Just need to use 
<a href="https://docs.python.org/3/library/itertools.html#itertools.product" rel="nofollow">itertools.product</a></p>

<pre><code>&gt;&gt;&gt; source = [['a', 'b', 'c'], [1, 2, 3]]
&gt;&gt;&gt; list(itertools.product(*source))
[('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3), ('c', 1), ('c', 2), ('c', 3)]
</code></pre>

<p>But I can't find the reverse operation. How to find the source <code>[['a', 'b', 'c'], [1, 2, 3]]</code> from the result of a product. Does anyone know the universal solution?</p>

<p>I appreciate any suggestions.</p>

<p>Its only a partial solution but assuming you <strong>know for certain</strong> that the result is a valid cartesian product generated by <code>itertools.product</code> and it is over lists of <strong>distinct</strong> values</p>

<pre><code>&gt;&gt;&gt; [list(collections.OrderedDict.fromkeys(y)) for y in zip(*cartesian_product)]
[['a', 'b', 'c'], [1, 2, 3]]
</code></pre>

<p>Here we simply use the <code>zip(*...)</code> idiom to unpack the tuples and then use <code>OrderedDict</code> in lieu of an <code>OrderedSet</code> to reduce them to their unique values.</p>

<p>This approach generalises to larger <code>itertools.product</code> of distinct values.  For example:</p>

<pre><code>&gt;&gt;&gt; source = [['a', 'b', 'c'], [1, 2, 3], [3, 5, 7]]
&gt;&gt;&gt; cartesian_product = itertools.product(*source)
&gt;&gt;&gt; [list(collections.OrderedDict.fromkeys(y)) for y in zip(*cartesian_product)]
[['a', 'b', 'c'], [1, 2, 3], [3, 5, 7]]
</code></pre>

python itertools