Python 更好的迭代模式,无需枚举

Python 更好的迭代模式,无需枚举,python,Python,我经常使用以下代码模式: def update_missing_content_type(cls): items_missing_content_type = ItemMaster.objects.filter(content_type__isnull=True) num_items = items_missing_content_type.count() for num, item in enumerate(items_missing_content_type):

我经常使用以下代码模式:

def update_missing_content_type(cls):
    items_missing_content_type = ItemMaster.objects.filter(content_type__isnull=True)
    num_items = items_missing_content_type.count()
    for num, item in enumerate(items_missing_content_type):
        if num % 100 == 0:
            log.info('>>> %s / %s updated...' % (num+1, num_items))
        # do something

如果查询的大小不是很小,则
枚举
可能是不理想的。但是,我仍然需要知道脚本的进度(它可能会运行十个小时,等等)

有什么比上面更好的模式可以在记录一般过程的同时对大量结果进行处理


如果查询的大小不是很小,则
枚举
可能是不理想的


enumerate
生成一个迭代器,而不是一个列表,因此它不会通过预先分配一堆内存来消耗额外的内存。另外,它在无限长生成器上不起作用。

枚举的行为类似于迭代器,将动态生成整数。详情如下: Enumerate在性能上应该表现得几乎相同,就像只是浏览iterable的索引并查找项一样

大概您需要有日志索引和
#do something
中的项目,这样我们就可以对两者进行计时。以下是我的结果:

python-m timeit-s'test=range(10)*1000''表示i,元素在枚举(test)中:通过'
1000个循环,最好3个:每个循环370 usec

python-m timeit-s'test=range(10)*1000''表示x范围内的i(len(test)):elem=test[i]'
1000个循环,最好3个:每个循环397 usec

在本用例中,这两种方法在速度上似乎没有预期的差异。但是,如果您不需要索引,则存在差异:
python-m timeit-s'test=range(10)*1000''用于测试中的元素:通过'

10000个循环,最好是每个循环3:153个usec

“如果列表/集合的大小非常小,
枚举
可能是不理想的。”-怎么会这样?@user2357112如果我有一个1000万个对象的查询集,我想迭代它,而不是将其转换为列表。
enumerate
不会将其转换为列表。@David542
enumerate
返回迭代器,而不是整个列表。
enumerate
不是生成器,也不涉及
yield
。它返回一个迭代器;生成器是实现迭代器的一种特定方式。@user2357112您是对的,源代码()在文档中使用了“yields”一词,但这不是语言规范所指的关键字
yield
。我的错误,我会相应地更新。