【问题标题】:Pythonic way to default loop counters默认循环计数器的 Pythonic 方式
【发布时间】:2018-03-18 00:11:04
【问题描述】:

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

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 中默认循环计数器的最佳实践或指南?

【问题讨论】:

    标签: python python-3.x for-loop counter


    【解决方案1】:

    我认为不存在最佳实践。我会做什么(为了不初始化为-1,然后需要做count + 1)将enumeratestart值设置为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 循环目标在循环后可见,因此您应该没问题。

    【讨论】:

    • 每天学习新东西。感谢您对enumeratestart 参数的提示。
    【解决方案2】:

    不知道你为什么使用enumerate。你不能只增加每个项目的计数器吗?

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

    【讨论】:

    • 恕我直言,使用枚举更 Pythonic!
    • @SRC 恕我直言,它不是。
    • 也许我错了,如果我错了,我很抱歉,但我从几个高票的 SO 帖子中得到了这个想法。前 - thisthis
    • @SRC 虽然我喜欢它,但 enumerate 在这里所做的是隐含的;依赖于 count 在 for 循环结束后被重新分配和可见的事实(尽管在文档中明确说明了这一点,但许多人可能不知道)。像 Stefan 建议的那样直言不讳可能会更好。
    • 我明白你的观点@Jim Fasarakis Hilliard 我想我现在明白这背后的逻辑了。感谢您清理它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 2015-04-26
    • 2018-04-28
    • 2016-10-10
    相关资源
    最近更新 更多