继续循环而不迭代

时间:2018-09-18 22:52:42

标签: python for-loop keyword

有没有可用于迭代for循环而无需执行迭代器的关键字?我知道可以通过使用while循环并手动迭代而无需这样的命令来执行此操作,但是在这种情况下,如果我可以仅使用for循环,它将大大简化操作,因为没有迭代就继续是例外,而不是规则。 (完成该操作后,将会添加更多的条件,所有这些都需要迭代)。这是我的代码(或者,到目前为止我写的):

for line in file_as_list:
    response = input(line)
    if response.lower() == 'help':
        self.show_command_list()
        response = input(line)
    if response.lower() == 'loc':
        self.show_location(file_as_list, location)
        response = input(line)
    if response.lower() == 'exit':
        save_changes = input('Would you like to save the changes you have made? (Y/N) ')
        while (save_changes.upper() != 'Y') & (save_changes.upper() != 'N'):
            save_changes = input('That is not a valid response. Try again. ')
        if save_changes.upper() == 'N':
            temp = file_as_list
            print('Changes were not saved.')
        else:
            for line in file_as_list[location:]:
                temp.append(line)
            print('Changes were saved.')
        break
    if response.lower() == 'inline':
        line += ' //' + input(line + ' //')
        print('Line generated: ' + line)
    location += 1
    temp.append(line)

3 个答案:

答案 0 :(得分:2)

我认为您需要两个嵌套循环。尝试这样的事情:

for line in file_as_list:   # outer loop
    while True:             # inner loop
        response = input(line).lower()
        if response == 'help':        # these two options don't exit the inner loop
            ...
        elif response == 'loc':       # so they won't consume a line from the for loop
            ...
        else:
            break

    if response == 'exit':            # these other two conditions are outside the while loop
        ...
    elif response == 'inline':        # so a new line will be fetched after they run
        ...

如果满足前两个条件中的任何一个,则内部循环将继续运行而无需更改line。仅当break被命中时,内循环才会结束,其他条件也将得到测试。他们做完事情后,随着line循环继续迭代,将为for分配一个新值。

与您的主要问题无关,我还更改了input行,以便在将输入保存到lower之前立即在输入上调用response。这意味着条件不需要继续重复调用它。您的代码并没有错,但是如果您从不关心用户的大小写,立即将其扔掉可以简化操作。

答案 1 :(得分:1)

您可以使用类似的显式迭代器

... else {
    $mysqli->error;  // log this and/or react to it somehow
}

,依此类推。只要确保正确处理行数不足的情况即可!

答案 2 :(得分:0)

您有两种类型的命令:一种用于推进迭代器的命令,另一种不用于执行迭代器的命令。您也可以将其称为动作vs描述性命令。从概念上讲,您最好的选择是拥有一个while循环,该循环将继续寻找输入,直到您收到操作命令为止。此while循环将存在于现有for循环中。

这样做的好处是,目前无法重复使用“ help”和“ loc”之类的描述性命令,但您可能希望重复使用它们。

我建议的另一个决定是使用不同的功能来实现每个命令。通过为命令提供一致的界面,可以使代码更易于维护和理解。通过将命令注册到字典中,可以使查找更快,更灵活。

以下概念具有一堆函数,这些函数返回三态布尔值和更新。如果命令希望停留在当前行,则布尔值为True,否则为False。没有退出。行更新通常只是输入。

# in __init__
...
   self.command_map = {
        'help': self.help,
        'loc': , self.loc,
        'exit': self.exit,
        'inline': self.inline,
    }
    self.temp = []
...

def help(self, file_as_list, location, line):
    self.show_command_list()
    return True, line

def loc(self, file_as_list, location, line):
    self.show_location(file_as_list, location)
    return True, line

def exit(self, file_as_list, location, line):
    save_changes = ''
    while len(save_changes) != 1 or save_changes.upper() not in 'YN':
        save_changes = input('Would you like to save the changes you have made? (Y/N) ')
    if save_changes.upper() == 'N':
        self.temp = file_as_list
        print('Changes were not saved.')
    else:
        self.temp.extend(file_as_list[location:])
        print('Changes were saved.')
    return None, line

def inline(self, file_as_list, location, line):
    line += ' //' + input(line + ' //')
    print('Line generated: ' + line)
    return True, line

def process(self):
    for location, line in enumerate(file_as_list):
        stay = True
        while stay:
            response = input(line)
            command = command_map.get(response.casefold())
            if command is None:
                print(f'Command "{response}" not found. Try again')
            else:
                stay, line = command(file_as_list, location, line)

        if stay is None:
            break
        self.temp.append(line)

鉴于command_map,您可以轻松完成很多事情:例如,您可以重新实现show_command_list以使用sorted(command_map.keys())做某事。我相信您可以看到将命令添加到列表中相对容易。您不必重复样板代码,只需小心输入和返回值即可。

如果您不喜欢嵌套循环的想法,则手动迭代此构造也容易得多:

def process(self):
    stay = False
    iterator = enumerate(file_as_list)
    while True:
        if not stay:
            try:
                location, line = next(iterator)
            except StopIteration:
                break
        response = input(line)
        command = command_map.get(response.casefold())
        if command is None:
            print(f'Command "{response}" not found. Try again')
            stay = True
        else:
            stay, line = command(file_as_list, location, line)

        if stay is None:
            break
        if not stay:
            self.temp.append(line)

如您所见,此方法需要针对各种条件进行更多特殊处理。