简体   繁体   English

遍历具有一定数量的1s,0s和-1s的列表

[英]Iterate over lists with a certain number of 1s, 0s and -1s

I can iterate over all lists with -1s, 0s and 1s with 我可以使用-1s,0s和1s遍历所有列表

for v in itertools.product([-1,0,1], repeat = n):

However, if I only want lists with A 1s, B 0s and C -1s, how can I iterate over those without making all the lists and filtering with if v.count(1)=A and v.count(0) = B and v.count(C)=-1 ? 但是,如果我只想要具有A 1s,B 0s和C if v.count(1)=A and v.count(0) = B and v.count(C)=-1的列表, if v.count(1)=A and v.count(0) = B and v.count(C)=-1情况下,如何在不进行所有列表筛选的情况下进行迭代if v.count(1)=A and v.count(0) = B and v.count(C)=-1

EDIT 编辑

Using itertools.permutations is very wasteful sadly as it makes the same tuple over and over again. 可悲的是,使用itertools.permutations会使同一元组一遍又一遍地浪费。

As len(list(itertools.permutations([1]*2 + [0]*2 + [-1]*2))) = 720 although len(set(itertools.permutations([1]*2 + [0]*2 + [-1]*2))) = 90 . 尽管len(set(itertools.permutations([1]*2 + [0]*2 + [-1]*2))) = 90 len(list(itertools.permutations([1]*2 + [0]*2 + [-1]*2))) = 720 len(set(itertools.permutations([1]*2 + [0]*2 + [-1]*2))) = 90

And we can see that permutations repeats tuples with 我们可以看到排列重复了

 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)]

Using itertools.permutations will produce duplicates. 使用itertools.permutations将产生重复项。 You can code it up yourself, and here's one way to do it. 您可以自己编写代码,这是一种实现方法。

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

What you want is actually permutations not product . 您想要的实际上是permutations而不是product

Create a function to wrap this functionality: 创建一个包装此功能的函数:

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

Usage Example: 用法示例:

>>> 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)

Explanation: 说明:

What you want to do is create a list which will be used to produce all the permutations, and you want this list to contain an amount of -1,0,1 s as you want. 您想要做的是创建一个列表,该列表将用于生成所有排列,并且您希望该列表包含所需的-1,0,1 s。 Lets start with creating a list full of 5 1's. 让我们从创建一个包含5个1的列表开始。 We can do that with: 我们可以这样做:

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

We can add this list to another list: 我们可以将此列表添加到另一个列表中:

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

And yet another: 还有一个:

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

And so, when you want to create your list, we get: 因此,当您要创建列表时,我们得到:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM