以下是我的代码:
import itertools
i = itertools.chain()
for a in [1, 2, 3]:
i = itertools.chain(i, (a for _ in range(2)))
print(list(i))
[3, 3, 3, 3, 3, 3]
在创建生成器时,有没有办法可以访问a
的值,而不是在print
语句中迭代它时?
我希望输出为[1,1,2,2,3,3]
,即创建生成器时a
的值。
这是一个微不足道的问题,但在我的情况下,我在外循环中迭代1,000,000行,然后在内循环中为每个百万行生成8行,所以我热衷于保持它为生成器。
的Nb。用例是我在外循环中迭代一个表,为每一行创建子对象,将主键传递给子对象。数字非常大,所以我想构建生成器,然后在循环后批量插入(使用Django' s Model.objects.bulk_create(generator)
)。但是当我调用bulk_create
时,主键始终设置为外循环中的最后一行。
gen = itertools.chain()
for id in ParentModel.objects.all().value_list('id', flat=True)):
gen = itertools.chain(gen, (InnerModel(fk=id) for i in range(10000)))
InnerModel.objects.bulk_create(gen)
所有生成的InnerModel都指向列表中的最后一个OuterModel。
答案 0 :(得分:2)
一种方法是重新构建代码以使用两个for
genexp,以便id
在需要时具有正确的值:
InnerModel.objects.bulk_create(
InnerModel(fk=id) for id in ParentModel.objects.all().value_list('id', flat=True)
for i in range(10000))
作为另一个好处,你不会得到你正在使用那些嵌套的chain
构建的令人讨厌的堆栈溢出。
答案 1 :(得分:1)
如果你不介意将元组包装成lambda:
>>> import itertools
>>> i = itertools.chain()
>>> for a in [1, 2, 3]:
>>> i = itertools.chain(i, (lambda x: (x for _ in range(2)))(a))
>>> print(list(i))
[1, 1, 2, 2, 3, 3]
想法是复制每次迭代的a
的值。 lambda
的论证可以做到这一点。在每次迭代中,创建局部变量x
并使用a
进行分配。