Search code examples
pythoncombinationspython-itertools

Combinations of a list of strings with exclusions


I am working on coming up with an exhaustive list of component operating states for a system. I need one operating state for each component. I have developed unique indices for each operating state, of the form component#-OS#, so if component 1 has three operating states, they would be 1-1, 1-2, 1-3 and so on. I want to exclude duplicate operating states for each component, so that only one of each component is present. I am using itertools combinations but need to figure out how to incorporate the exclusions in an efficient way (my problem is much bigger than the sample problem below):

 from itertools import combinations
 indices=["1-1", "1-2", "1-3", "2-1", "2-2", "3-1", "3-2", "4-1", "4-2", "4-3", "5-1", "5-2", "5-3"]
 out=list(combinations(indices, 5))

As it is written now, out contains many duplicate operating states and is much longer than I would like. I could easily filter them out after the fact but this will be a very time consuming effort. When I take this to the full scale problem, there will be hundreds of millions of combinations so I need to figure out a way to efficiently restrict the output to include only a single operating state for each component. This may involve modifying the combinations function somehow but I'm not sure where to start.

Any ideas?

EDIT

To clarify, I'm hoping for output of the form:

[1-1, 2-1, 3-1, 4-1, 5-1], [1-2, 2-1, 3-1, 4-1, 5-1]...[1-3, 2-2, 3-2, 4-3, 5-3]


Solution

  • You should separate the states for each component into a list of its own, and use itertools.product.

    from itertools import groupby, product
    statelist = ["1-1", "1-2", "1-3", "2-1", "2-2", "3-1", "3-2", "4-1", "4-2", "4-3", "5-1", "5-2", "5-3"]
    statelist = (list(b) for a, b in groupby(statelist, lambda x: x.partition('-')[0]))
    out = list(product(*statelist))