Reputation: 424
I know there is a very similar question: Itertools product without repeating duplicates
but I have something different. For example:
a = ['add', 'sub']
b = [2,3, 'a', 'b']
c = [1,3, 'a', 'c']
list(it.product(a, b, c)) # result is:[('add', 2, 1),('add', 2, 3),('add', 2, 'a'), ('add', 2, 'c'),
#('add', 3, 1),('add', 3, 3),('add', 3, 'a'),('add', 3, 'c'),('add', 'a', 1),('add', 'a', 3),
#('add', 'a', 'a'),('add', 'a', 'c'), ('add', 'b', 1),('add', 'b', 3),('add', 'b', 'a'),
#('add', 'b', 'c'),('sub', 2, 1),('sub', 2, 3),('sub', 2, 'a'),('sub', 2, 'c'),('sub', 3, 1),
#('sub', 3, 3),('sub', 3, 'a'),('sub', 3, 'c'),('sub', 'a', 1),('sub', 'a', 3),('sub', 'a', 'a'),
#('sub', 'a', 'c'),('sub', 'b', 1),('sub', 'b', 3),('sub', 'b', 'a'),('sub', 'b', 'c')]
for the result:
I don't want add(a,a)
, as the first value == second value.
I want to keep only 1 of add(3,a)
, add(a,3)
, as it is symmetric.
and my example only contains two list, but I may use 5 or more lists to generate product.
I cant use combinations
, because:
product(['add', 'sub', 1,2,3, 'a','b', 'c'], repeat=3)
is different with product(['add', 'sub'], [2,3, 'a', 'b'], [1,3, 'a', 'c'])
Something in product(['add', 'sub', 1,2,3, 'a','b', 'c'], repeat=3)
is not ok for me.
I want a fast method, since my program is time sensitive.
Upvotes: 0
Views: 526
Reputation: 61910
IIUC, you could do:
from itertools import product, combinations, chain
a = ['add', 'sub']
b = [2, 3, 'a', 'b']
c = [1, 3, 'a', 'c']
for operation, operands in product(a, combinations(set(chain(b, c)), r=2)):
print((operation, *operands))
Output
('add', 1, 2)
('add', 1, 3)
('add', 1, 'a')
('add', 1, 'b')
('add', 1, 'c')
('add', 2, 3)
('add', 2, 'a')
('add', 2, 'b')
('add', 2, 'c')
('add', 3, 'a')
('add', 3, 'b')
('add', 3, 'c')
('add', 'a', 'b')
('add', 'a', 'c')
('add', 'b', 'c')
('sub', 1, 2)
('sub', 1, 3)
('sub', 1, 'a')
('sub', 1, 'b')
('sub', 1, 'c')
('sub', 2, 3)
('sub', 2, 'a')
('sub', 2, 'b')
('sub', 2, 'c')
('sub', 3, 'a')
('sub', 3, 'b')
('sub', 3, 'c')
('sub', 'a', 'b')
('sub', 'a', 'c')
('sub', 'b', 'c')
Upvotes: 2