代码之家  ›  专栏  ›  技术社区  ›  sodiumnitrate

涉及itertools的两个嵌套for循环不会产生外循环的置换

  •  0
  • sodiumnitrate  · 技术社区  · 4 年前

    我有以下代码:

    a = [0,1,2,3,4]
    b = range(6)
    p = itertools.permutations(a)
    p2 = itertools.product(b,b,b,b,b)
    
    for pos in p:
        for shift in p2:
            print(pos,shift)
    

    打印出:

    (0, 1, 2, 3, 4) (0, 0, 0, 0, 0)
    (0, 1, 2, 3, 4) (0, 0, 0, 0, 1)
    (0, 1, 2, 3, 4) (0, 0, 0, 0, 2)
    (0, 1, 2, 3, 4) (0, 0, 0, 0, 3)
    (0, 1, 2, 3, 4) (0, 0, 0, 0, 4)
    ...
    (0, 1, 2, 3, 4) (5, 5, 5, 5, 5)
    

    外部循环只执行一次。如果我这样做了

    for pos in p:
        print(pos)
    

    循环执行得很好:

    (0, 1, 2, 3, 4)
    (0, 1, 2, 4, 3)
    ...
    (4, 3, 2, 1, 0)
    

    为什么会发生这种情况,以及如何使这两个嵌套的for循环工作?请注意,我已经尝试过循环 list(p) 而不仅仅是 p 这也没什么区别。

    1 回复  |  直到 4 年前
        1
  •  3
  •   flakes    4 年前

    代码运行不符合预期的原因与此不起作用的原因相同:

    p = iter(range(6))
    p2 = iter(range(6))
    
    for pos in p:
        for shift in p2:
            print(pos,shift)
    

    itertools.product 返回只能使用一次的迭代器。第一次循环 p2 您已经消耗了所有的值,外部循环的后续迭代本质上变成了禁止操作。

    您需要将迭代器输出存储到一个可以多次迭代的容器中,或者调用 itertools。产品 根据需要进行多次重建。

    import itertools
    
    a = [0,1,2,3,4]
    b = range(6)
    p = itertools.permutations(a)
    p2 = list(itertools.product(b,b,b,b,b))
    
    for pos in p:
        for shift in p2:
            print(pos,shift)
    

    import itertools
    
    a = [0,1,2,3,4]
    b = range(6)
    p = itertools.permutations(a)
    
    for pos in p:
        p2 = itertools.product(b,b,b,b,b)
        for shift in p2:
            print(pos,shift)
    

    注:实际上 permutations product 方法实际上是用于生成特定于操作的类的构造函数调用,然而,它们确实实现了迭代器接口,所以我只是这样调用它们!