在Python中测试空迭代器。。。环

2024-06-02 06:12:27 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的代码基于this recipe。然而,配方的关键点——如果迭代器为空,它提供了在迭代器上中断迭代的方法——在这里似乎不起作用,而是以以下不希望的方式运行:

  1. 如果get_yes_no_answer()==False并且迭代器中还有两个或更多项,则跳过下一个_选项,而不是在下一个迭代中被选中。
  2. 如果get_yes_no_answer()==False并且迭代器中只剩下不到两个项,则my_func()返回None。

我如何确保:

  • 如果get_yes_no_answer()==False并且迭代器中还有两个或多个项,则下一个选择是否被跳过?
  • 如果get_yes_no_answer()==False并且迭代器中还有一个项,则my_func()打印它并调用get_yes_no_answer()
  • 如果get_yes_no_answer()==False并且迭代器中没有剩余项,则触发except StopIteration子句?

代码如下:

def my_func(choice_pattern, input):
# Search in input for some things to choose from.
choice_iterator = choice_pattern.finditer(input, re.M)
if not choice_iterator:
    print "No choices. Exiting..."
    sys.exit()
else:
    # Show choices to the user. For each one, ask user for a yes/no response. If
    # choice accepted, return a result. Otherwise show user next choice. If no
    # choices accepted by user, quit.
    for choice in choice_iterator:
        print choice.group()
        # get_yes_no_answer() returns True or False depending on user response.
        if get_yes_no_answer():
            return choice
        else:
            # Check if iterator is empty. If so, quit; if not, do something else.
            try:
                next_choice = choice_iterator.next()
            except StopIteration:
                print "No matches. Exiting..."
                sys.exit()
            else:
                choice_iterator = itertools.chain([next_choice], choice_iterator)

Tags: noanswerfalseforinputgetifmy
3条回答

您不需要检查迭代器是否为空。for循环将为您执行此操作,并在迭代器为空时停止。就这么简单。

另外,在sys.exit()或返回之后不需要else

完成后,您的代码如下所示:

def my_func(choice_pattern, input):
    # Search in input for some things to choose from.
    choice_iterator = choice_pattern.finditer(input, re.M)
    if not choice_iterator:
        print "No choices. Exiting..."
        sys.exit()

    # Show choices to the user. For each one, ask user for a yes/no response. If
    # choice accepted, return a result. Otherwise show user next choice. If no
    # choices accepted by user, quit.
    for choice in choice_iterator:
        print choice
        # get_yes_no_answer() returns True or False depending on user response.
        if get_yes_no_answer():
            return choice
    # Loop exited without matches.
    print "No matches. Exiting..."
    sys.exit()

就这样!

结果是你在循环中,也会得到下一个项目。结果是你事实上只显示每一秒的答案。

事实上,您可以简化它:

def my_func(choice_pattern, input):
    choice_iterator = choice_pattern.finditer(input, re.M)
    if choice_iterator:
        for choice in choice_iterator:
            print choice
            if get_yes_no_answer():
                return choice
    # If there is no choices or no matches, you end up here:
    print "No matches. Exiting..."
    sys.exit()

迭代器几乎和任何序列类型一样使用。你不需要把它和单子区别对待。

请参阅this question中的成对迭代器。然后您可以检查最后一个项目,如:

MISSING = object()
for choice, next_choice in pairwise(chain(choice_iterator, [MISSING])):
    print(choice.group())
    if get_yes_no_answer():
        return choice.group()
    if next_choice is MISSING:
        print("No matches. Exiting...")
        sys.exit()

在你展示的例子中,这似乎没有必要。您不需要检查finditer是否返回了迭代器,因为它总是返回迭代器。如果你找不到你想要的东西,你就可以掉入for循环:

def my_func(choice_pattern, input):
    """Search in input for some things to choose from."""
    for choice in choice_pattern.finditer(input, re.M):
        print(choice.group())
        if get_yes_no_answer():
            return choice.group()
    else:
        print("No choices. Exiting...")
        sys.exit()

你为什么这么做?为什么不:

def get_choice(pattern, inpt):
    choices = pattern.finditer(inpt, re.M)
    if not choices:
        sys.exit('No choices')
    for choice in choices:
        print(choice.group(0))
        if get_yes_no_answer():
            return choice
    sys.exit('No matches')

我不知道你输入的长度是多少,但我怀疑这样做值得。

相关问题 更多 >