在Python中,如何为迭代对象多次迭代?

时间:2016-02-20 10:16:07

标签: python

我遇到了一些从Dynamo数据库中获取迭代对象的代码,我可以这样做:

print [en["student_id"] for en in enrollments]

然而,当我再次做类似的事情时:

print [en["course_id"] for en in enrollments]

然后第二次迭代将不打印任何内容,因为迭代结构只能迭代一次并且它已经到达终点。

问题是,对于(1)如果已知迭代中只有几个项目(2)如果我们知道会有很多项目(如果我们知道会有很多项目),我们怎么能多次迭代呢?在迭代中说一百万个项目,我们不想花费大量额外的内存空间吗?

相关的是,我查了rewind,它似乎存在于PHP和Ruby中,但不适用于Python?

2 个答案:

答案 0 :(得分:6)

enrollments是一个生成器。如果您需要再次迭代,或者首先将其转换为列表,重新创建生成器:

enrollments = list(enrollments)

考虑到API通常使用生成器来避免内存膨胀;列表必须引用它包含的所有对象,因此所有这些对象必须同时存在。发电机可以根据需要逐个生产元件;一旦提取出'student_id'密钥,列表理解就会再次丢弃这些对象。

另一种方法是迭代一次,并使用你想要做的每个对象 all 。因此,不是运行两个列表推导,而是运行一个常规的for循环,并在一个地方提取您需要的所有数据,随着时间的推移附加到单独的列表中:

courses = []
students = []
for enrollment in enrollments:
    courses.append(enrollment['course_id'])
    students.append(enrollment['student_id'])
PHP中的

rewind与此无关; Python有fileobj.seek(0)来做同样的事情,但文件对象不是生成器。

答案 1 :(得分:0)

import itertools
it1, it2 = itertools.tee(enrollments, n=2) 

从这里看起来是一个答案:Why can't I iterate twice over the same data? 但它只有在你不太多次迭代时才有效。