PyMongo 不会迭代集合 [英] PyMongo doesn't iterate over collection

查看:135
本文介绍了PyMongo 不会迭代集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have strange behaviour in Python/PyMongo.

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 并按索引获取但没有)

and it prints only 120 times (1..120) and not 20x120 times. Can someone tell me why it doesn't iterate through outer collection ? I printed results, it always takes only first of outer and iterates over inner collection. ( I posted counts which I get in code 20 and 120, I tried with xrange and fetch by index but nothing)

推荐答案

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

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 中的数据.

.rewind() resets cursor to a fresh state, enabling you to once again retrieve data in second_collection_records.

说明:

second.find()

返回一个包含迭代器的 Cursor 对象.

returns a Cursor object, which contains an iterator.

当 Cursor 的迭代器到达终点时,它不再返回任何内容.

When an iterator of Cursor reach its end, it no longer return anything.

因此:

for f in first_collection_records: #20

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

actually does iterated 20 times, but since the inner:

for s in second_collection_records:

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

already iterated all objects returned, the second time it is called, second_collection_records no longer returns anything, thus the code inside(i=i+1, print...) is not executed.

你可以这样试试:

i = 0
for f in first_collection_records:
    print "in f"
    for s in second_collection_records: 
        print "inside s"

你会得到一个结果:

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

<小时>

深入解释:

这一行:

for s in second_collection_records: 

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

the loop here actually works by next() method of Cursor object, as in: calling second_collection_records.next() until second_collection_records raised StopIteration exception (In Python generator and for loop, StopIteration is caught and code inside for loop would not be executed). So in the second til last loop of first_collection_records, second_collection_records.next() actually raised StopIteration for the inner loop, not executing the code.

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

We can easily observe this behavior by doing this:

for f in first_collection_records:
    print "inside f"
    second_collection_records.next()
    for s in second_collection_records:
        print "inside s"

结果:

inside f
inside s
...
inside s
inside f
Traceback (most recent call last):
  ... , in next
    raise StopIteration
StopIteration

这篇关于PyMongo 不会迭代集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆