首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PyMongo不会遍历集合

PyMongo不会遍历集合
EN

Stack Overflow用户
提问于 2012-03-20 23:20:36
回答 1查看 4.2K关注 0票数 4

我在Python/PyMongo中有奇怪的行为。

代码语言:javascript
复制
dbh = self.__connection__['test']
first = dbh['test_1']
second = dbh['test_2']

first_collection_records=first.find()  
second_collection_records=second.find()


index_f=first_collection_records.count() //20 
index_s=second_collection_records.count() //120

i=0
for f in first_collection_records:
    for s in second_collection_records:
         i=i+1
         print i

而且它只打印120次(1..120),而不是20x120次。有人能告诉我为什么它不遍历外部集合吗?我打印了结果,它总是只需要外部的第一个,并在内部集合上迭代。(我发布了我在代码20和120中获得的计数,我尝试了xrange和fetch by index,但什么都没有)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-20 23:43:59

如果你想为每个first_collection_records迭代second_collection_records,你可以使用:

代码语言:javascript
复制
i=0
for f in first_collection_records:
    second_collection_records.rewind() #Reset second_collection_records's iterator
    for s in second_collection_records:
         i=i+1
         print i

.rewind()将游标重置为新状态,使您能够再次在second_collection_records中检索数据。

说明:

代码语言:javascript
复制
second.find()

返回包含迭代器的Cursor对象。

当游标的迭代器到达其末尾时,它不再返回任何内容。

因此:

代码语言:javascript
复制
for f in first_collection_records: #20

实际上确实迭代了20次,但由于内部:

代码语言:javascript
复制
for s in second_collection_records:

已经迭代了返回的所有对象,第二次调用时,second_collection_records不再返回任何内容,因此里面的代码(i=i+1,print...)不会被执行。

您可以像这样尝试:

代码语言:javascript
复制
i = 0
for f in first_collection_records:
    print "in f"
    for s in second_collection_records: 
        print "inside s"

你会得到一个结果:

代码语言:javascript
复制
inside f
inside s
inside s
...
inside s
inside f  <- since s has nothing left to be iterated, 
             (second_collection_records actually raised StopIteration such in generator),
             code inside for s in second_collection_records: is no longer executed
inside f
inside f

深度解释:

这一行:

代码语言:javascript
复制
for s in second_collection_records: 

这里的循环实际上是通过Cursor对象的next()方法工作的,如下所示:调用second_collection_records.next()直到second_collection_records引发StopIteration异常(在Python生成器和for循环中,StopIteration被捕获,for循环中的代码将不会被执行)。因此,在first_collection_records的第二个til last循环中,second_collection_records.next()实际上为内部循环引发了StopIteration,而不是执行代码。

通过这样做,我们可以很容易地观察到这种行为:

代码语言:javascript
复制
for f in first_collection_records:
    print "inside f"
    second_collection_records.next()
    for s in second_collection_records:
        print "inside s"

结果是:

代码语言:javascript
复制
inside f
inside s
...
inside s
inside f
Traceback (most recent call last):
  ... , in next
    raise StopIteration
StopIteration
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9789601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档