iItertools.product with variable validation
<p>I have this form of list</p>

<pre><code>data = [
   [
    {'name': 's11', 'class': 'c1'}, {'name': 's12', 'class': 'c2'}
   ],
   [
    {'name': 's21', 'class': 'c2'}, {'name': 's22', 'class': 'c2'}
   ],
   [
    {'name': 's31', 'class': 'c1'}, {'name': 's32', 'class': 'c1'}
   ]
]
</code></pre>

<p>by using the <code>itertools.product(data)</code>
I receive all the possible combinations needed by taking one element from each list in the main list data.
What I want to do, I want to skip if the element in the first sublist have a different class in the second or third sublist.</p>

<p>Does itertools.product provide any validation options for such case ?</p>

<p>The expected results should be:</p>

<pre><code>({'name': 's11', 'class': 'c1'},{'name': 's31', 'class': 'c1'}),
( {'name': 's11', 'class': 'c1'}, {'name': 's32', 'class': 'c1'}),
({'name': 's12', 'class': 'c2'},{'name': 's21', 'class': 'c2'}),
({'name': 's12', 'class': 'c2'},{'name': 's22', 'class': 'c2'}),
</code></pre>

<p>Almost the same as @skovorodkin posted.</p>

<pre><code>from itertools import product, chain

data = [
    [{'name': 's11', 'class': 'c1'}, {'name': 's12', 'class': 'c2'}],
    [{'name': 's21', 'class': 'c2'}, {'name': 's22', 'class': 'c2'}],
    [{'name': 's31', 'class': 'c1'}, {'name': 's32', 'class': 'c1'}]
]
output = [i for i in product(data[0], chain.from_iterable(data[1:])) if i[0]['class'] == i[1]['class']]
output
</code></pre>

<p>Output:</p>

<pre><code>[({'class': 'c1', 'name': 's11'}, {'class': 'c1', 'name': 's31'}),
 ({'class': 'c1', 'name': 's11'}, {'class': 'c1', 'name': 's32'}),
 ({'class': 'c2', 'name': 's12'}, {'class': 'c2', 'name': 's21'}),
 ({'class': 'c2', 'name': 's12'}, {'class': 'c2', 'name': 's22'})]
</code></pre>

<p><strong>UPDATE</strong></p>

<p>Just a little comparison. I just used the default data and the time results are the following:</p>

<p>@skovorodkin answer:</p>

<pre><code>&gt;&gt;&gt; %timeit result = [(a, b) for a, b in chain.from_iterable(product(*l) for l in combinations(data, 2)) if a['class'] == b['class']]
The slowest run took 8.56 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 3.69 Âµs per loop
</code></pre>

<p>My answer:</p>

<pre><code>&gt;&gt;&gt; %timeit output = [i for i in product(data[0], chain.from_iterable(data[1:])) if i[0]['class'] == i[1]['class']]
The slowest run took 10.37 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 2.43 Âµs per loop
</code></pre>

python list dictionary itertools