Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 模型的嵌套置换_Python_Algorithm_Permutation_Combinatorics_Itertools - Fatal编程技术网

Python 模型的嵌套置换

Python 模型的嵌套置换,python,algorithm,permutation,combinatorics,itertools,Python,Algorithm,Permutation,Combinatorics,Itertools,我正在编写一个程序,它采用字符串的排列“模型”,并根据该模型输出所有排列。模型的外观如下所示: model = Mix([ [ "this", PickOne(["is", "isn't"]) ], PickOne([ Mix([ "absolutely", "great" ]) ]) ]) class Mix(list): def __ini

我正在编写一个程序,它采用字符串的排列“模型”,并根据该模型输出所有排列。模型的外观如下所示:

model = Mix([
    [
        "this",
        PickOne(["is", "isn't"])
    ],
    PickOne([
        Mix([
            "absolutely",
            "great"
        ])
    ])
])
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)
在输出的排列中

  • 列表
    对象将按顺序输出包含的对象
  • Mix
    对象将以任何可能的最大长度(包括零)以每个可能的顺序输出包含的对象
  • PickOne
    对象一次只输出其包含的一个对象
  • 因此,上述示例的期望输出为:

    [
        ["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"],
        []
    ]
    
    到目前为止,我已经为
    Mix
    类实现了如下排列:

    model = Mix([
        [
            "this",
            PickOne(["is", "isn't"])
        ],
        PickOne([
            Mix([
                "absolutely",
                "great"
            ])
        ])
    ])
    
    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)
    
    我的
    PickOne
    课程就是这样

    class PickOne(list):
        pass
    
    我正计划在我的主函数中对其进行测试并进行相应的处理(
    如果type(obj)是PickOne:…


    itertools
    为更简单的用例提供了简化和效率,但是我不知道它将如何帮助我实现这个实现(除了我在
    Mix
    中已经实现的之外)。关于如何使用
    itertools
    来帮助上述的Pythonic实现,您有什么想法吗?

    我对所有这些组合感到困惑,但我认为您的
    Mix
    类还必须生成所有这些
    排列的
    产品。我创建了一个类似的模型来测试这一点。这可能与您的工作方式有所不同,但应易于适应:

    class CombModel:
        def __init__(self, *options):
            self.options = options
    
    class Atom(CombModel):
        def __iter__(self):
            for x in self.options:
                yield x
    
    class All(CombModel):
        def __iter__(self):
            for prod in itertools.product(*self.options):
                yield prod
    
    class One(CombModel):
        def __iter__(self):
            for x in self.options:
                for y in x:
                    yield y
    
    class Mix(CombModel):
        def __iter__(self):
            for n in range(len(self.options) + 1):
                for perm in itertools.permutations(self.options, n):
                    for prod in itertools.product(*perm):
                        yield prod
    
    CombModel
    仅为所有子类提供var-arg构造函数
    Atom
    是模型中的一个“叶子”,因此我可以“迭代”单个字符串或整数。这将在所有其他类中保存一些
    if/else
    逻辑
    All
    在您的模型中似乎是简单的列表,生成不同选项的产品
    One
    Mix
    对应于您的
    PickOne
    Mix

    使用这个相当简单的模型
    comb=Mix(全部(原子(1),原子(21,22)),一个(原子(31,32),原子(4))
    我得到了以下组合:

    ()
    ((1, 21),)
    ((1, 22),)
    (31,)
    (32,)
    (4,)
    ((1, 21), 31)
    ((1, 21), 32)
    ((1, 21), 4)
    ((1, 22), 31)
    ((1, 22), 32)
    ((1, 22), 4)
    (31, (1, 21))
    (31, (1, 22))
    (32, (1, 21))
    (32, (1, 22))
    (4, (1, 21))
    (4, (1, 22))
    
    ()
    (('this', 'is'),)
    (('this', "isn't"),)
    ((),)
    (('absolutely',),)
    (('great',),)
    (('absolutely', 'great'),)
    (('great', 'absolutely'),)
    (('this', 'is'), ())
    (('this', 'is'), ('absolutely',))
    (('this', 'is'), ('great',))
    (('this', 'is'), ('absolutely', 'great'))
    (('this', 'is'), ('great', 'absolutely'))
    (('this', "isn't"), ())
    (('this', "isn't"), ('absolutely',))
    (('this', "isn't"), ('great',))
    (('this', "isn't"), ('absolutely', 'great'))
    (('this', "isn't"), ('great', 'absolutely'))
    ((), ('this', 'is'))
    ((), ('this', "isn't"))
    (('absolutely',), ('this', 'is'))
    (('absolutely',), ('this', "isn't"))
    (('great',), ('this', 'is'))
    (('great',), ('this', "isn't"))
    (('absolutely', 'great'), ('this', 'is'))
    (('absolutely', 'great'), ('this', "isn't"))
    (('great', 'absolutely'), ('this', 'is'))
    (('great', 'absolutely'), ('this', "isn't"))
    
    您的模型可以解释为:

    model = Mix(
        All(
            Atom("this"),
            One(Atom("is"), Atom("isn't"))
        ),
        One(
            Mix(
                Atom("absolutely"),
                Atom("great")
            )
        )
    )
    
    并给出了这些组合:

    ()
    ((1, 21),)
    ((1, 22),)
    (31,)
    (32,)
    (4,)
    ((1, 21), 31)
    ((1, 21), 32)
    ((1, 21), 4)
    ((1, 22), 31)
    ((1, 22), 32)
    ((1, 22), 4)
    (31, (1, 21))
    (31, (1, 22))
    (32, (1, 21))
    (32, (1, 22))
    (4, (1, 21))
    (4, (1, 22))
    
    ()
    (('this', 'is'),)
    (('this', "isn't"),)
    ((),)
    (('absolutely',),)
    (('great',),)
    (('absolutely', 'great'),)
    (('great', 'absolutely'),)
    (('this', 'is'), ())
    (('this', 'is'), ('absolutely',))
    (('this', 'is'), ('great',))
    (('this', 'is'), ('absolutely', 'great'))
    (('this', 'is'), ('great', 'absolutely'))
    (('this', "isn't"), ())
    (('this', "isn't"), ('absolutely',))
    (('this', "isn't"), ('great',))
    (('this', "isn't"), ('absolutely', 'great'))
    (('this', "isn't"), ('great', 'absolutely'))
    ((), ('this', 'is'))
    ((), ('this', "isn't"))
    (('absolutely',), ('this', 'is'))
    (('absolutely',), ('this', "isn't"))
    (('great',), ('this', 'is'))
    (('great',), ('this', "isn't"))
    (('absolutely', 'great'), ('this', 'is'))
    (('absolutely', 'great'), ('this', "isn't"))
    (('great', 'absolutely'), ('this', 'is'))
    (('great', 'absolutely'), ('this', "isn't"))
    
    请注意,这些仍然是嵌套列表(实际上是元组),但之后可以很容易地进行嵌套。此外,由于
    Mix
    的“零或多”特性,存在一些伪重复(展平时即为重复)。但除此之外,这看起来相当接近您的预期输出


    仔细检查后,可能确实需要先展平,以便PickOne只从混合物中选择一种,而不是整个混合物

    class All(CombModel):
        def __iter__(self):
            for prod in itertools.product(*self.options):
                yield flat(prod) # flatten here
    
    class One(CombModel):
        def __iter__(self):
            for x in self.options:
                for y in flat(x): # flatten here
                    yield y
    
    class Mix(CombModel):
        def __iter__(self):
            for n in range(len(self.options) + 1):
                for perm in itertools.permutations(self.options, n):
                    for prod in itertools.product(*perm):
                        yield flat(prod) # flatten here
    
    剔除重复项后,结果如下:

    ()
    ('absolutely',)
    ('absolutely', 'this', 'is')
    ('absolutely', 'this', "isn't")
    ('great',)
    ('great', 'this', 'is')
    ('great', 'this', "isn't")
    ('this', 'is')
    ('this', 'is', 'absolutely')
    ('this', 'is', 'great')
    ('this', "isn't")
    ('this', "isn't", 'absolutely')
    ('this', "isn't", 'great')
    

    我很难理解这一点。因此,即使是一个简单的“列表”,如果它包含其他“排列模型”,也应该产生这些模型所有可能结果的乘积,对吗?没错。嗯,当一个
    One
    包含一个
    All
    对象时,这似乎不起作用-它不选择整个
    All
    ,而是选择其内部内容之一。这里有一个要点:@Julien这不就是它的工作原理吗?至少这与您的示例中一个(Mix(…)的工作方式是一致的。另外,我的第一个版本,并没有扁平化,应该像这样工作,一个选择所有的内容。你们说得对。我的规范并不完美,但我通过在
    All
    中省略
    flatten
    实现了我所需要的功能。再次感谢