return 对 2 个变量 i,j 使用带 if 语句的 for 循环时为空列表 python

return empty list when using a for loop with if statement for a 2 variables i,j python

我想将一些元素添加到满足条件的列表中,所以我使用生成器制作了一个for循环来完成它。当我使用同一个生成器制作第二个列表时,问题就出现了。问题是第一个得到了我想要的元素,第二个 returns 是空的。这是代码:

import itertools
n = 4
xxvars = [["x."+str(i+1)+"."+str(j+1) for j in range(n)]for i in range(n)]
yyvars = [["y."+str(i+1)+"."+str(j+1) for j in range(n)]for i in range(n)]

gen = ((i,j) for i,j in itertools.product(range(n),range(1,n)) if i != j)

thevars1 = [xxvars[i][j] for (i,j) in gen]
thevars2 = [yyvars[i][j]for (i,j) in gen]

这个returns:

thevars1 = ['x.1.2','x.1.3','x.1.4','x.2.3','x.2.4','x.3.2','x.3.4','x.4.2','x.4.3']
thevars2 = []

所需的输出应该是:

thevars1 = ['x.1.2','x.1.3','x.1.4','x.2.3','x.2.4','x.3.2','x.3.4','x.4.2','x.4.3']
thevars2 = ['y.1.2','y.1.3','y.1.4','y.2.3','y.2.4','y.3.2','y.3.4','y.4.2','y.4.3']

是我的代码有问题,还是我遗漏了什么?

一旦生成器表达式迭代了一次,就不能再迭代了。

您可以通过 运行 next(gen) 验证这一点,这会引发 StopIteration 异常。

>>> next(gen)
Traceback (most recent call last):
  File "<ipython-input-41-8a6233884a6c>", line 1, in <module>
    next(gen)
StopIteration

要多次使用一个生成器,您可以 return 从函数中使用它

def create_generator():
    return ((i, j) for i, j in itertools.product(range(n), range(1,n)) if i != j)

或使用生成器语法

def create_generator():
    for i,j in itertools.product(range(n),range(1,n)):
        if i != j:
            yield i, j

那么你可以称它为

thevars1=[xxvars[i][j] for (i,j) in create_generator()]
thevars2=[yyvars[i][j]for (i,j) in create_generator()]

因为gen是一个生成器对象。生成器对象一旦被使用,就不能再使用。你必须召回它才能再次生成生成器对象。

其他两个答案都是正确的。这是完成您想要的任务的一种方法:

import itertools
n=4
xxvars=[["x."+str(i+1)+"."+str(j+1) for j in range(n)]for i in range(n)]
yyvars=[["y."+str(i+1)+"."+str(j+1) for j in range(n)]for i in range(n)]

def f():
    return ((i,j) for i,j in itertools.product(range(n),range(1,n)) if i!=j)
thevars1=[xxvars[i][j] for (i,j) in f()]
thevars2=[yyvars[i][j] for (i,j) in f()]