没有枚举的更好的迭代模式

时间:2015-07-02 21:26:09

标签: 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):
        if num % 100 == 0:
            log.info('>>> %s / %s updated...' % (num+1, num_items))
        # do something

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

在记录其一般过程的同时,在多个结果上执行某些操作会比上述更好的模式?

2 个答案:

答案 0 :(得分:1)

  

如果查询的大小不重要,enumerate可能是不理想的。

build.gradle生成一个迭代器,而不是一个列表,所以它不会通过预先分配一堆内存而耗尽额外的内存。另外,它不会对无限长的发电机起作用。

答案 1 :(得分:1)

枚举表现为迭代器,并将动态生成整数编号。更多详情:What is the implementation detail for enumerate? 枚举应该在性能上几乎完全相同,只是遍历可迭代的索引并查找项目。

大概你需要记录日志和#do something中的项目,所以我们可以计算两者。以下是我的结果:

python -m timeit -s 'test=range(10)*1000' 'for i, elem in enumerate(test): pass' 1000 loops, best of 3: 370 usec per loop

python -m timeit -s 'test=range(10)*1000' 'for i in xrange(len(test)): elem=test[i]' 1000 loops, best of 3: 397 usec per loop

在这个用例中,两者之间的速度似乎没有差异。但是,如果您不需要索引,则会有所不同: python -m timeit -s 'test=range(10)*1000' 'for elem in test: pass' 10000 loops, best of 3: 153 usec per loop