6

I'm trying to do some combinatorial stuff with data in Python. I looked the question How to generate all permutations of a list in Python, but think that doesn't fit my needs.. I have data of this type...:

    group1-Steve
    group1-Mark
    group1-Tom
    group2-Brett
    group2-Mick
    group2-Foo
    group3-Dan
    group3-Phil

...and i need to make all possible combinations of three elements with only one from each group, without repetitions, saving to a list every combination.

I know in this case there are 18 possible different combinations(3*3*2=18), but don't know how could i write this code. I ve read about the Pyncomb package, but don't know the function to apply in this case; maybe there's a function which does the job.

Hope anyone could help me...

Thanks in advance;

Peixe

Community
  • 1
  • 1
peixe
  • 1,272
  • 3
  • 14
  • 31

2 Answers2

9

The easiest way is to use itertools.product():

group1 = ["Steve", "Mark", "Tom"]
group2 = ["Brett", "Mick", "Foo"]
group3 = ["Dan", "Phil"]
for x in itertools.product(group1, group2, group3):
    print x

prints

('Steve', 'Brett', 'Dan')
('Steve', 'Brett', 'Phil')
('Steve', 'Mick', 'Dan')
('Steve', 'Mick', 'Phil')
('Steve', 'Foo', 'Dan')
('Steve', 'Foo', 'Phil')
('Mark', 'Brett', 'Dan')
('Mark', 'Brett', 'Phil')
('Mark', 'Mick', 'Dan')
('Mark', 'Mick', 'Phil')
('Mark', 'Foo', 'Dan')
('Mark', 'Foo', 'Phil')
('Tom', 'Brett', 'Dan')
('Tom', 'Brett', 'Phil')
('Tom', 'Mick', 'Dan')
('Tom', 'Mick', 'Phil')
('Tom', 'Foo', 'Dan')
('Tom', 'Foo', 'Phil')
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • Oh yes!! I ve been trying with tenths of code lines, but this solution is really amazing and simple. :DD Thank u very much, Sven!!! – peixe Jun 05 '11 at 19:12
4

Another alternative which avoids the import is to use a list comprehension:

[(a, b, c) for a in group1 for b in group2 for c in group3]

This gives the same result as Sven's but is nice if you want to do some filtering too.

PAG
  • 1,836
  • 1
  • 18
  • 19
  • I'll give a try to this solution, as well. As I have to manage pretty huge amounts of data arranged in this way, i finally select the most efficient one. ;D Thanks, PAG! – peixe Jun 05 '11 at 19:31
  • 1
    This may be more efficient, particularly if you change those square brackets to parentheses: for x in ((a, b, c) for a ....): .... – PAG Jun 05 '11 at 19:35
  • The most important difference between the two approaches is that `itertools.product()` can also be used if you don't know the number of groups in advance, while this approach hardcodes the number of groups. – Sven Marnach Jun 05 '11 at 19:49
  • Right, e.g. a nice pattern for generating binary numbers of size n as tuples is itertools.product(*[(0, 1)] * n) – PAG Jun 05 '11 at 21:28
  • Given that the number of groups will vary in every case, think that will be more efficient using the "import" option... – peixe Jun 05 '11 at 21:50