6

While writing a program that finds all the different combos for a list, I found a lot of threads about using intertools.product() instead of intertools.combinations_with_replacement(), as I have been doing. No one explained why you should use intertools.product. I would love to know how this affects my program output.

Torkoal
  • 457
  • 5
  • 17

3 Answers3

6

From Python documentation

itertools.product(*iterables[, repeat])

Cartesian product of input iterables.

Equivalent to nested for-loops in a generator expression. For example, product(A, B) returns the same as ((x,y) for x in A for y in B).

In other words:

for x, y in itertools.product(A, B):

replaces

for x in A:
    for y in B:
............

EDIT:

  • itertolls.combinations_with_replacement() will take single iterable and produce all possible combinations of its elements of given length;

  • itertools.product() will produce combination of values from several iterables, where element 0 of the resulting tuple is from the first iterable, element 1 - from second, etc.

volcano
  • 3,578
  • 21
  • 28
  • 2
    while correct and certainly better than the current accepted answer, this does not answer how it compares to `combinations_with_replacement`, which was the explicit question. – KillianDS Jan 20 '14 at 06:26
  • @KillianDS, quoting OP __No one explained why you should use intertools.product__. But I will elaborate – volcano Jan 20 '14 at 06:41
  • @KillianDS, BTW, the accepted answer is simply wrong and misleading – volcano Jan 20 '14 at 06:51
  • This was very very helpful. I fixed my program with this. Thanks so much! – Torkoal Jan 21 '14 at 03:11
3

This chunk of code will help you understand.

from itertools import combinations_with_replacement
from itertools import product

string = input()

for ele in list(combinations_with_replacement(string,2)):
    print("".join(ele), end=' ')

print()

prod = list(product(string,repeat = 2))
for ele in prod:
    print("".join(ele), end=' ')

INPUT

ABCD

OUTPUT

AA AB AC AD BB BC BD CC CD DD 
AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD 

EDIT:

As you can see the output of combinations_with_replacement() generates every possible combination of elements from first one to last ie 'AA AB AC AD' then it goes to generate the every possible combination of remaining elements with the second one to last one ie 'BB BC BD' note that it does't go back from second element to first element. In case of product() the output generated is from first element to second element as well as second to first i.e. AB and BA this goes on till the end of the iterable.

  • Hi @RajatTarade welcome to SO. not sure if by just posting the code you are explaining the differences between the two functions. Good answers usually come with detailed or concise explanations and are not code only – StupidWolf Jun 28 '20 at 16:35
  • combinations_with_replacement() will generate both AB and BA. combinations() will only generate AB – keenan Oct 05 '22 at 18:43
1

If someone else stumbles over this question like I did: On the itertools documentation there is a example where you clearly can see the difference between the results of the 4 combinatoric iterators.

product('ABCD', repeat=2)
AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD

All values are combined together, even with itself (AA).


permutations('ABCD', 2)
AB AC AD BA BC BD CA CB CD DA DB DC

Only values that don't match the iterating value are combined together (AB).


combinations('ABCD', 2)
AB AC AD BC BD CD

Only values that don't match the iterating value are combined together, but in sorted order there are no duplicates (AB / BA).


combinations_with_replacement('ABCD', 2) 
AA AB AC AD BB BC BD CC CD DD

All values are combined together, even with itself (AA), but in sorted order there are no duplicates (AB / BA).