Shachar183
Shachar183

Reputation: 25

How to do a Cartesian product for words in a list using Python

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

Answers (3)

WorldSEnder
WorldSEnder

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

Oldest Software Guy
Oldest Software Guy

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

pzp
pzp

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

Related Questions