PyMongo 不会迭代集合

2024-03-30

我在 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 并按索引获取,但什么也没有)


如果你想为每个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() 将游标重置为新状态,使您能够再次检索 secondary_collection_records 中的数据。


解释:

second.find()

返回一个 Cursor 对象,其中包含一个迭代器。

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

thus:

for f in first_collection_records: #20

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

for s in second_collection_records:

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

你可以这样尝试:

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() 方法来工作的,如下所示:调用 secondary_collection_records.next() 直到 secondary_collection_records 引发 StopIteration 异常(在 Python 生成器和 for 循环中,StopIteration 被捕获,并且 for 循环内的代码不会被执行)。因此,在first_collection_records的第二个到最后一个循环中,second_collection_records.next()实际上为内部循环引发了StopIteration,而不是执行代码。

我们可以通过这样做轻松观察到这种行为:

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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PyMongo 不会迭代集合 的相关文章

随机推荐