生成所有排列,其中排列的长度> Python中的元素数

时间:2018-07-13 18:04:56

标签: python algorithm permutation

我想从这些元素生成置换(元组):

[None, 0, 1, 2]. 

我希望每个排列的长度为5,并且始终包含3个None。此类排列的一个示例:

(None, 0, None, None, 1).

我目前已在Python 3.x中创建了此算法:

[state for state in list(set(it.permutations((None, None, None, 0, 0, 1, 1, 2, 2), 5))) if state.count(None)==3]

但是,我觉得这个算法不是最理想的(而且很丑陋),我不确定它是否正确。有更好的解决方案吗?我细读了NumPy,但没有发现任何对我有帮助的东西。

感谢您的帮助!

5 个答案:

答案 0 :(得分:0)

您可以创建一个递归函数:

def group(d, current = [], in_place = [None, 3]):
  need, _occurs = in_place
  if len(current) == 5 and current.count(need) == _occurs:
    yield current
  else:
    for i in d:
      _c = current+[i]
      if len(_c) <= 5 and _c.count(need) <= _occurs:
        yield from group(d, current = _c)

输出:

[[None, None, None, 0, 0], [None, None, None, 0, 1], [None, None, None, 0, 2], [None, None, None, 1, 0], [None, None, None, 1, 1], [None, None, None, 1, 2], [None, None, None, 2, 0], [None, None, None, 2, 1], [None, None, None, 2, 2], [None, None, 0, None, 0], [None, None, 0, None, 1], [None, None, 0, None, 2], [None, None, 0, 0, None], [None, None, 0, 1, None], [None, None, 0, 2, None], [None, None, 1, None, 0], [None, None, 1, None, 1], [None, None, 1, None, 2], [None, None, 1, 0, None], [None, None, 1, 1, None], [None, None, 1, 2, None], [None, None, 2, None, 0], [None, None, 2, None, 1], [None, None, 2, None, 2], [None, None, 2, 0, None], [None, None, 2, 1, None], [None, None, 2, 2, None], [None, 0, None, None, 0], [None, 0, None, None, 1], [None, 0, None, None, 2], [None, 0, None, 0, None], [None, 0, None, 1, None], [None, 0, None, 2, None], [None, 0, 0, None, None], [None, 0, 1, None, None], [None, 0, 2, None, None], [None, 1, None, None, 0], [None, 1, None, None, 1], [None, 1, None, None, 2], [None, 1, None, 0, None], [None, 1, None, 1, None], [None, 1, None, 2, None], [None, 1, 0, None, None], [None, 1, 1, None, None], [None, 1, 2, None, None], [None, 2, None, None, 0], [None, 2, None, None, 1], [None, 2, None, None, 2], [None, 2, None, 0, None], [None, 2, None, 1, None], [None, 2, None, 2, None], [None, 2, 0, None, None], [None, 2, 1, None, None], [None, 2, 2, None, None], [0, None, None, None, 0], [0, None, None, None, 1], [0, None, None, None, 2], [0, None, None, 0, None], [0, None, None, 1, None], [0, None, None, 2, None], [0, None, 0, None, None], [0, None, 1, None, None], [0, None, 2, None, None], [0, 0, None, None, None], [0, 1, None, None, None], [0, 2, None, None, None], [1, None, None, None, 0], [1, None, None, None, 1], [1, None, None, None, 2], [1, None, None, 0, None], [1, None, None, 1, None], [1, None, None, 2, None], [1, None, 0, None, None], [1, None, 1, None, None], [1, None, 2, None, None], [1, 0, None, None, None], [1, 1, None, None, None], [1, 2, None, None, None], [2, None, None, None, 0], [2, None, None, None, 1], [2, None, None, None, 2], [2, None, None, 0, None], [2, None, None, 1, None], [2, None, None, 2, None], [2, None, 0, None, None], [2, None, 1, None, None], [2, None, 2, None, None], [2, 0, None, None, None], [2, 1, None, None, None], [2, 2, None, None, None]]

答案 1 :(得分:0)

如果我真的不想生成并过滤掉一堆不适当的条目,这就是我要采取的方法:

您需要0到3个None(呼叫号码n1),然后是列表中的一个非None项目,然后是0到3-{{1} } n1None),然后是列表中的第二个非n2项目,然后是3-None-n1 {{1} } s。

n2

答案 2 :(得分:0)

假设(从代码的输出以及您故意添加0、1和2的多个副本的事实)您正在执行“置换置换”,或者基本上是满足您的3 Nones要求的笛卡尔乘积,我会做类似的事情:

for fund in alerter.fund:
     alerter.positions_file_search(fund)
    etc...

与您的输出匹配的

def tien_gen(size, values, number_of_nones):
    to_fill = size - number_of_nones
    for locs in itertools.combinations(range(size), to_fill):
        for fill_values in itertools.product(values, repeat=to_fill):
            out = [None] * size
            for loc, fill_value in zip(locs, fill_values):
                out[loc] = fill_value
            yield tuple(out)

对于小尺寸,优点是有限的,但对于大尺寸,这样可以避免生成任何不使用的元组,并且由于它是生成器,因此如果不使用,则不必全部实现它们想。

答案 3 :(得分:0)

从概念上讲,我认为最简单的“有效”算法可以解释为:首先生成长度为2的排列。然后,以所有可能的方式插入None的3个实例。

但是,相反,它更有效:首先,在您希望两个元素都位于的位置生成所有索引。然后,对于长度2的每个排列的每个索引集,将这些元素替换为给定索引。

from itertools import combinations, permutations, product

base_list = [None] * 5
values = [0, 1, 2]

all_indices = combinations(range(5), 2)
all_perms = permutations(values, 2)

for (i, j), (x, y) in product(all_indices, all_perms):
    list_copy = base_list[:]
    list_copy[i] = x
    list_copy[j] = y
    print(list_copy)

# [0, 1, None, None, None]
# [0, 2, None, None, None]
# ...
# [None, None, None, 2, 0]
# [None, None, None, 2, 1]

对于不同长度的输入,这应该很容易扩展。

def inserted_permutations(size, values, insert_count, default=None):
    base = [default] * size
    all_indices = combinations(range(size), insert_count)
    all_perms = permutations(values, insert_count)
    for indices, values in product(all_indices, all_perms):
        base_copy = base[:]
        for index, value in zip(indices, values):
            base_copy[index] = value
        yield base_copy

答案 4 :(得分:-1)

from itertools import product

elemets = [None, 0, 1, 2]
l = product(elemets, repeat=5)
s = set(p for p in l if p.count(None) == 3)

print(s)

输出:

{(None, None, None, 0, 2), (None, None, 0, None, 2), (1, 2, None, None, None), (0, None, None, 1, None), (1, None, 2, None, None), (1, None, None, 2, None), (None, 2, 1, None, None), (None, None, None, 2, 1), (None, None, 2, None, 1), (None, None, None, 1, 1), (None, 0, None, 0, None), (None, 0, 0, None, None), (None, 1, None, None, 1), (2, 1, None, None, None), (2, None, None, 1, None), (None, 0, None, None, 1), (None, 0, None, 1, None), (0, None, None, 0, None), (0, None, 0, None, None), (None, None, 1, 1, None), (1, None, None, 1, None), (2, None, None, 2, None), (2, None, 2, None, None), (None, None, 2, None, 0), (None, None, None, 2, 0), (None, None, None, 1, 2), (0, 0, None, None, None), (None, 0, None, None, 0), (2, 0, None, None, None), (None, None, 0, 1, None), (None, None, 1, 2, None), (None, 0, None, 2, None), (None, 0, 2, None, None), (0, 1, None, None, None), (None, 2, None, 2, None), (None, 2, 2, None, None), (None, 1, None, 1, None), (None, None, 1, None, 0), (2, None, None, None, 2), (2, 2, None, None, None), (2, None, None, 0, None), (2, None, 0, None, None), (None, 1, None, 2, None), (None, 1, 2, None, None), (0, None, 1, None, None), (0, None, None, None, 1), (None, None, None, 0, 1), (None, None, 0, None, 1), (None, 2, None, 1, None), (None, 0, None, None, 2), (None, None, 1, None, 1), (2, None, 1, None, None), (2, None, None, None, 1), (None, None, 0, 2, None), (1, None, None, None, 0), (None, 1, None, None, 2), (None, 0, 1, None, None), (0, None, None, None, 2), (None, 2, None, None, 2), (0, None, None, None, 0), (None, None, 0, 0, None), (None, None, 2, 2, None), (None, None, None, 0, 0), (None, None, 0, None, 0), (None, 2, None, 0, None), (None, 2, 0, None, None), (1, None, 1, None, None), (None, None, 1, None, 2), (2, None, None, None, 0), (0, 2, None, None, None), (1, None, None, 0, None), (1, None, None, None, 1), (1, None, 0, None, None), (None, None, 1, 0, None), (None, 1, None, 0, None), (None, 1, 0, None, None), (None, None, 2, 1, None), (None, 2, None, None, 1), (1, 1, None, None, None), (None, None, None, 2, 2), (1, None, None, None, 2), (0, None, None, 2, None), (0, None, 2, None, None), (None, 1, 1, None, None), (None, None, None, 1, 0), (None, None, 2, None, 2), (None, 1, None, None, 0), (None, None, 2, 0, None), (1, 0, None, None, None), (None, 2, None, None, 0)}