默认循环计数器的 Pythonic 方式
Pythonic way to default loop counters
我有时会使用生成器来过滤程序中的某些值,并希望记录过滤后的项目。
让我们假设:
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 循环目标在循环后可见这一事实,所以您应该没问题。
不确定为什么要使用 enumerate
。不能只增加每个项目的计数器吗?
def process_items(items):
count = 0
for item in filter_items(items):
item.do_stuff()
count += 1
print('Processed', count, 'items.')
我有时会使用生成器来过滤程序中的某些值,并希望记录过滤后的项目。
让我们假设:
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 循环目标在循环后可见这一事实,所以您应该没问题。
不确定为什么要使用 enumerate
。不能只增加每个项目的计数器吗?
def process_items(items):
count = 0
for item in filter_items(items):
item.do_stuff()
count += 1
print('Processed', count, 'items.')