Skip to main content
 首页 » 编程设计

默认循环计数器的 Pythonic 方式

2025年05月04日10zhwl

我有时会使用生成器来过滤程序中的某些值,并希望记录过滤后的项目。
让我们假设:

def filter_items(items): 
    for item in items: 
        if item.is_wanted(): 
            yield item 
 
def process_items(items): 
    for item in filter_items(items): 
        item.do_stuff() 

现在我的问题是我想记录实际调用了多少筛选项。
目前我这样做:

def process_items(items): 
    for count, item in enumerate(filter_items(items)): 
        item.do_stuff() 
 
    try: 
        count += 1 
    except UnboundLocalError: 
        count = 0 
 
    print('Processed', count, 'items.') 

现在我觉得检查 UnboundLocalError 有点奇怪,所以我考虑改为默认计数器:

def process_items(items): 
    count = -1 
 
    for count, item in enumerate(filter_items(items)): 
        item.do_stuff() 
 
    print('Processed', count + 1, 'items.') 

然而,将默认计数器设置为 -1 看起来也很奇怪,因为没有迭代的实际默认值将是 0。 但是我不能将它默认为 0,因为这样我就无法区分默认值(如果没有元素被迭代)或是否有一个元素被迭代。

是否有关于 Python 中循环计数器默认设置的最佳实践或指南?

请您参考如下方法:

我认为不存在最佳实践。我会做的(为了不初始化为 -1 然后需要做 count + 1)是设置 enumerate 的 start 值到 1:

def process_items(items): 
    count = 0     
    for count, item in enumerate(filter_items(items), start=1): 
        item.do_stuff() 
 
    print('Processed', count, 'items.') 

这让我清楚发生了什么。 (注意start=1可以写成1)。

请注意,是的,这不是执行此操作的最明确方法(请参阅 Stefan 的回答)。由于您确实知道 for 循环目标在循环后可见这一事实,所以您应该没问题。