Nested Permutations from Model

Viewed 127

I'm writing a program that takes a permutations "model" of strings, and outputs all permutations according to that model. The model looks something like this:

model = Mix([
    [
        "this",
        PickOne(["is", "isn't"])
    ],
    PickOne([
        Mix([
            "absolutely",
            "great"
        ])
    ])
])

Within the outputted permutations,

  1. list objects will output the containing objects in sequence
  2. Mix objects will output the containing objects in every possible order with ever possible max length (including zero)
  3. PickOne objects will output only one of its containing objects at a time

So, the desired output of the above example would be:

[
    ["this", "is"],
    ["this", "isn't"],
    ["this", "is", "absolutely"],
    ["this", "is", "great"],
    ["this", "isn't", "absolutely"],
    ["this", "isn't", "great"],
    ["absolutely"],
    ["great"],
    ["absolutely", "this", "is"],
    ["great", "this", "is"],
    ["absolutely", "this", "isn't"],
    ["great", "this", "isn't"],
    []
]

So far, I've implemented the permutations for the Mix class like this:

class Mix(list):
    def __init__(self, *args, **kwargs):
        super(Mix, self).__init__(*args, **kwargs)
        self.permutations = []
        for L in range(0, len(self)+1):
            for subset in itertools.combinations(self, L):
                subset_permutations = itertools.permutations(subset)
                self.permutations.extend(subset_permutations)

and my PickOne class is simply this

class PickOne(list):
    pass

which I'm planning on just testing for in my main function and handling accordingly (if type(obj) is PickOne: ...).

itertools provides simplification and efficiency for simpler use-cases, however I'm at a loss on how it will help me for this implementation (beyond what I already implemented in Mix). Any ideas of how itertools can be used to help in a Pythonic implementation of the above?

1 Answers
Related