迭代3个列表的更好方法

Sur*_*ari 7 python

我正在创建一个程序,它迭代图像的宽度和高度,并使用一组键.

这是一个例子:

width = [0,1,2,3,4,6,7,8,9]
height = [0,1,2,3,4]
keys = [18,20,11]
Run Code Online (Sandbox Code Playgroud)

宽度和高度是一个整数范围,直到宽度和高度的大小.键是任何一组数字(实际上是ASCII值),但不是有序数字.

我想输出是这样的:

0 0 18
0 1 20
0 2 11
0 3 18
0 4 20
1 0 11
1 1 18
. . ..
9 0 20
9 1 11
9 2 18
9 3 20
9 4 11
Run Code Online (Sandbox Code Playgroud)

如您所见,宽度和高度可以使用嵌套for循环生成,而键可以在彼此之间循环.

这是我的解决方案:

w = [0,1,2,3,4,6,7,8,9]
h = [0,1,2,3,4]
k = [18,20,11]

kIndex = 0

for i in w:
    for j in h:
        print(i,j,k[kIndex])
        # Cycle through the keys index.
        # The modulo is used to return to the beginning of the keys list
        kIndex = (kIndex + 1) % len(k)
Run Code Online (Sandbox Code Playgroud)

实际上它按预期工作,但是,我想要一种更有效的方法来执行上述操作,而不是使用增量变量作为键列表的索引位置.

我不介意嵌套的for循环,如果必须使用它,但索引键变量让我烦恼,因为看起来没有它,代码将无法工作,但同时并不是真正的pythonic.

Oli*_*çon 11

您可以使用itertools.product获得宽度和高度的产品,即整个网格.最后,你想循环键,从而使用itertools.cycle.然后你们zip在一起并获得理想的结果.

你可以使用它来yield实现内存效率.

from itertools import product, cycle

def get_grid(width, height, keys):
    for pos, key in zip(product(width, height), cycle(keys)):
        yield (*pos, key)
Run Code Online (Sandbox Code Playgroud)

或者如果你不想要发电机.

out = [(*pos, key) for pos, key in zip(product(width, height), cycle(keys))]
Run Code Online (Sandbox Code Playgroud)

width = [0,1,2,3,4,6,7,8,9]
height = [0,1,2,3,4]
keys = [18,20,11]

for triple in get_grid(width, height, keys):
    print(triple)
Run Code Online (Sandbox Code Playgroud)

产量

(0, 0, 18)
(0, 1, 20)
(0, 2, 11)
(0, 3, 18)
(0, 4, 20)
(1, 0, 11)
(1, 1, 18)
...
Run Code Online (Sandbox Code Playgroud)

作为旁注,请注意您可以替换定义的列表widthheight范围.

width = range(10)
height = range(5)
Run Code Online (Sandbox Code Playgroud)