迭代具有一定数量的1,0和-1的列表

时间:2013-12-22 15:17:35

标签: python

我可以使用

遍历-1s,0和1的所有列表
for v in itertools.product([-1,0,1], repeat = n):

但是,如果我只想要包含A 1s,B 0s和C -1s的列表,那么如何在不创建所有列表的情况下迭代这些列表并使用if v.count(1)=A and v.count(0) = B and v.count(C)=-1进行过滤?

修改

使用itertools.permutations非常浪费,因为它一遍又一遍地生成相同的元组。

len(list(itertools.permutations([1]*2 + [0]*2 + [-1]*2))) = 720虽然len(set(itertools.permutations([1]*2 + [0]*2 + [-1]*2))) = 90

我们可以看到排列用

重复元组
 print list(itertools.permutations([1]*1 + [0]*1 + [-1]*2))
[(1, 0, -1, -1), (1, 0, -1, -1), (1, -1, 0, -1), (1, -1, -1, 0), (1, -1, 0, -1), (1, -1, -1, 0), (0, 1, -1, -1), (0, 1, -1, -1), (0, -1, 1, -1), (0, -1, -1, 1), (0, -1, 1, -1), (0, -1, -1, 1), (-1, 1, 0, -1), (-1, 1, -1, 0), (-1, 0, 1, -1), (-1, 0, -1, 1), (-1, -1, 1, 0), (-1, -1, 0, 1), (-1, 1, 0, -1), (-1, 1, -1, 0), (-1, 0, 1, -1), (-1, 0, -1, 1), (-1, -1, 1, 0), (-1, -1, 0, 1)]

2 个答案:

答案 0 :(得分:3)

使用itertools.permutations将产生重复项。你可以自己编写代码,这是一种方法。

def uniq_perms(a, b, c):
    if a < 0 or b < 0 or c < 0:
        return
    if a + b + c == 0:
        yield []
    for s in uniq_perms(a - 1, b, c):
        yield [0] + s
    for s in uniq_perms(a, b - 1, c):
        yield [1] + s
    for s in uniq_perms(a, b, c - 1):
        yield [-1] + s

for s in uniq_perms(2, 1, 1):
    print s

答案 1 :(得分:1)

您想要的实际上是permutations而不是product

创建一个包含此功能的函数:

def foo(A, B, C):
    return itertools.permutations([1]*A + [0]*B + [-1]*C)

用法示例:

>>> for v in foo(1,1,1):
    print v

(1, 0, -1)    (-1, 1, 0)
(-1, 0, 1)    (0, 1, -1)
(0, -1, 1)    (1, -1, 0)


>>> for v in foo(2,1,1):
    print v

(1, 1, 0, -1)    (1, 0, 1, -1)    (0, -1, 1, 1)
(1, 1, -1, 0)    (1, 0, -1, 1)    (0, -1, 1, 1)
(1, 0, 1, -1)    (1, -1, 1, 0)    (-1, 1, 1, 0)
(1, 0, -1, 1)    (1, -1, 0, 1)    (-1, 1, 0, 1)
(1, -1, 1, 0)    (0, 1, 1, -1)    (-1, 1, 1, 0)
(1, -1, 0, 1)    (0, 1, -1, 1)    (-1, 1, 0, 1)
(1, 1, 0, -1)    (0, 1, 1, -1)    (-1, 0, 1, 1)
(1, 1, -1, 0)    (0, 1, -1, 1)    (-1, 0, 1, 1)

<强>解释

您要做的是创建一个列表,该列表将用于生成所有排列,并且您希望此列表包含一定数量的-1,0,1 s。让我们从创建一个完整的5 1的列表开始。我们可以这样做:

>>> [1]*5
[1, 1, 1, 1, 1]

我们可以将此列表添加到另一个列表中:

>>> [1]*5 + [0]*2
[1, 1, 1, 1, 1, 0, 0]

而另一个:

>>> [1]*5 + [0]*2 + [-1]*7
[1, 1, 1, 1, 1, 0, 0, -1, -1, -1, -1, -1, -1, -1]

因此,当您想要创建列表时,我们会得到:

[1]*A + [0]*B + [-1]*C