Reputation: 25
It turned out I was looking for combinations and not the Cartesian product.
I need to do a Cartesian product of several words (all of them inside a list).
My input looks something like this:
[[id, [word1,word2,word3]],[id2,[word4,word5,word6]]]
The product needs to be made on the words in the first index inside each list of lists. Meaning - on word1, words2, and word3 between themselves, on word4, words5, and word6 between themselves and so on.
My code so far:
for row in x:
row[1] = list(itertools.product(*row[1])
The problem is that the script does the product on each of the letters and not on each one of the words.
I get something like: (w,w,w), (w,o,r), (w,o,d)
, etc.
The expected output is: (word1,word2), (word1,word3), (word2,word3)
. The same thing for the other parts..
Upvotes: 1
Views: 626
Reputation: 5044
itertools.product
takes several iterables as input. The Cartesian product is taken between the iterables given. E.g. itertools.product([1, 2], [3, 4])
gives [(1, 3), (1, 4), (2, 3), (2, 4)]
.
Having said that, what you actually meant to call was itertools.combinations
for row in x:
row[1] = list(itertools.combinations(row[1], 2))
Upvotes: 2
Reputation: 741
1 #!/usr/bin/python
2 # vim: noet sw=4 ts=4
3
4 d = [["id", ["word1","word2","word3"]],["id2"["word4","word5","word6"]]]
5 inner = d[0][1]
6 outer = d[1][1]
7 for o in outer:
8 for i in inner:
9 print '{0}x{1}'.format( i, o )
word1xword4
word2xword4
word3xword4
word1xword5
word2xword5
word3xword5
word1xword6
word2xword6
word3xword6
Upvotes: 0
Reputation: 6597
You're looking for [list(itertools.product(row[1], repeat=len(row[1]))) for row in x]
. You do not need to use the *
operator to unpack row[1]
, as itertools.product()
takes whole iterables as arguments. To calculate the Cartesian Product of each row "between themselves", use the repeat paramater.
Upvotes: 1