如何在“while”循环中出现错误后返回特定点

时间:2015-10-06 03:33:59

标签: python loops python-3.x while-loop continue

我正在尝试编写一个包含while循环的程序,在此循环中,如果出现错误,我会收到错误消息。它有点像这样;

while True:

    questionx = input("....")
    if x =="SomethingWrongabout questionX":
        print ("Something went wrong.")
        continue
    other codes...

    questiony = input("....")
    if y == "SomethingWrongabout questionY":
        print ("Something went wrong.")
        continue

    other codes...

    questionz = input("....")
    if z == "SomethingWrongabout questionZ":
       print ("Something went wrong.")
       continue

    other codes..

问题如下:当questionX之后发生错误时,程序进入开始状态。它从头开始,而不是从yz开始。但是在x没有问题,因此,程序应该开始向yz提问,因为问题发生在yz

如何让程序从特定点开始,例如只有在y问题时出现错误,程序必须开始向y提问或仅在z处提问,程序必须从z开始,而不是从x开始。

我应该为此使用多个while循环,还是只有在一个循环中才能使用它?

11 个答案:

答案 0 :(得分:8)

[从发电机到功能的编辑]

你可以尝试一个功能:

def check_answer(question, answer):
    while True:
        current_answer = input(question)
        if current_answer == answer:
            break
        print "Something wrong with question {}".format(question)
    return current_answer

answerX = check_answer("Question about X?\n", "TrueX")
answerY = check_answer("Question about Y?\n", "TrueY")
answerZ = check_answer("Question about Z?\n", "TrueZ")

不确定是否要保留这些值,但如果您需要调整它,这应该给您提示。

结果:

Question about X?
"blah"
Something wrong with question Question about X?

Question about X?
"blah"
Something wrong with question Question about X?

Question about X?
"TrueX"
Question about Y?
"TrueY"
Question about Z?
"blah"
Something wrong with question Question about Z?

Question about Z?
"blah"
Something wrong with question Question about Z?

Question about Z?
"TrueZ"

根据评论编辑:

def check_answer(question, answers):
    while True:
        current_answer = input(question)
        if current_answer in answers:
            break
        print "Something wrong with question {}".format(question)
    return current_answer

answerX = check_answer("Question about X?\n", ("TrueX", "TrueY")

答案 1 :(得分:5)

我认为这里有两个非常简单优雅的解决方案。

这个想法是有一个问题清单。只要问题仍然存在,两种实现都会继续询问。只要问题的答案是正确的,另一个做了不同的事情,就会使用map方法从列表中删除元素 - 见下文。

在这个示例实现中,神奇的答案是' foo'对任何问题都是错误的答案。您可以在Python中运行它,以检查它是否会重新询问您回答的问题(剩余)问题' foo'。

通过修改itertools.dropwhile()功能,可以直接适应您的情况。

ask_question()

修改 所以,在幕后,还有两个while循环(import itertools input = lambda x: raw_input("what is your "+x+"? ") # returns true or false; wether or not the question was answered # correctly def ask_question(question): answer = input(question) # could be any test involving answer return answer != "foo" # assume we have a list of questions to ask questions = [ "age", "height", "dog's name" ] # keep on looping until there are questions while questions: questions = list(itertools.dropwhile(ask_question, questions)) 是赠品:-))。通过一些开箱即用的思考,即使没有一个while循环也可以完成:

递归这个词!

takewhile()

如果您愿意,可以将其压缩为:

def ask_more_questions(question_list):
    # no more questions? then we're done
    if not question_list:
        return
    # ask the first question in the list ...
    if ask_question(question_list[0]):
        # ok, this one was answered fine, continue with the remainder
        ask_more_questions(question_list[1:])
    else:
        # Incorrect answer, try again with the same list of questions
        ask_more_questions(question_list)

答案 2 :(得分:2)

您误解了继续使用的方式,继续移动到循环的下一次迭代。要解决此问题,请删除继续

基于评论的编辑::

我只使用while True值,因为我对您的系统一无所知

while True:
    while True:
        questionx = input("....")
        if x =="SomethingWrongabout questionX":
            print ("Something went wrong.")
            continue
        else:
            break;

利用break将帮助您实现您想要的目标

答案 3 :(得分:2)

问题将由多个while循环解决。这些循环是在一个地方,还是在功能/发生器等中被考虑在内,是你的选择。

如果是我,我会将询问问题的代码分解为一个问题本身的函数,再加上验证代码来验证答案 - 函数会一直询问问题直到验证通过:

def ask_question(question, validate):
    while "not valid":
        answer = input(question)
        if validate(answer):
            return answer
        else:
            print(" invalid response, try again")

while True:

    x = ask_question("....", lambda a: a=="SomethingWrongabout questionX")

    ...other codes...

    y = ask_questiony("....", lambda a: a== "SomethingWrongabout questionY")

    ...other codes...

    z = ask_questionz("....", lambda a: a=="SomethingWrongabout questionZ")

答案 4 :(得分:1)

是的,除了通过循环之外,没有办法在执行后返回代码中的前一行。 完全没有办法

Python和许多现代编程语言以这种方式工作,并且不支持" goto"线。

因此,这就是唯一的方法是通过某种形式的多个while循环来重复执行一个语句,直到收到你想要的结果(嵌套循环,或者将while循环拉出到函数中) salparadise建议。)

答案 5 :(得分:1)

是否可以将代码放入函数中?知道问题遵循任意顺序,如果答案不符合您的标准,您可以使用try / except块,并保留已经回答的问题列表。

假设我们有一个全球清单:

answered_questions = []

还有一个辅助函数让我根据前面列表的长度来检查问题是否已经得到解答:

def is_it_answered(index):
    """
    Ckecks whether the question number "index" has already been answered.
    :param index: Number of question inside answered_questions
    :return: True if the question was already asked
    """
    # Checking for the index value to be True may not be necessary, but it's just for safety
    if len(answered_questions) >= index + 1 and answered_questions[index]:
        return True

现在,您在main函数内部所要做的就是在每个套件中放入与每个问题对应的代码。如果输入了你不想要的答案,那么在完成该问题背后的逻辑之前,不要在做任何你想做的事情之前提出异常。

def ask_questions():

    if not is_it_answered(0):
        try:
            answered_questions.append(True)
            questionx = input("...")

            # Whatever is supposed to make Question X wrong goes here
            if questionx == "not what i want":
                raise Exception

        except Exception:
            print "Something went wrong in question x"
            # do whatever you want to do regarding questionx being wrong
            ask_questions()

        # Rest of Code for Question X if everything goes right

    if not is_it_answered(1):
        try:
            answered_questions.append(True)
            questiony = input("...")

            # Whatever is supposed to make Question Y wrong goes here
            if questiony == "not what i want":
                raise Exception

        except Exception:
            print("Something went wrong")
            # do whatever you want to do regarding questionxy being wrong
            ask_questions()

        # Rest of Code for Question Y if everything goes right

    if not is_it_answered(2):
        try:
            answered_questions.append(True)
            questionz = input("...")

            # Whatever is supposed to make Question Z wrong goes here
            if questionz == "not what i want":
                raise Exception

        except Exception:
            print("Something went wrong")
            ask_questions()

        # Rest of Code for Question Z

        # If this is the last question, you can now call other function or end

if __name__ == "__main__":
    ask_questions()

在此代码中,键入“not what my want”将引发Exception,而在except块内,将再次调用您的函数。请注意,任何未在if条件中缩进的代码都会重复多次询问问题,这是一种预防措施。

答案 6 :(得分:1)

使用迭代器迭代问题,在获得所需的输出之前不要在迭代器上调用next:

questions = iter(("who is foo", "who is bar", "who is foobar"))
def ask(questions):
    quest = next(questions)
    while quest:
        inp = input(quest)
        if inp != "whatever":
            print("some error")
        else:
            print("all good")
            quest = next(quest, "")

如果您有问题和答案,请将它们拼接在一起:

def ask(questions, answers):
    zipped = zip(questions,answers) # itertools.izip python2
    quest,ans = next(zipped)
    while quest:
        inp = input(quest)
        if inp != ans:
            print("Wrong")
        else:
            print("all good")
            quest, ans = next(zipped, ("",""))

答案 7 :(得分:1)

在进入循环之前,将xyz设置为None。然后使用if保护每个问题,并在None之前将相关变量再次设置为continue

x = y = z = None
while True:

    if x is None:
        questionx = input("....")
        if x =="SomethingWrongabout questionX":
            print ("Something went wrong.")
            x = None
            continue

        other codes...

    if y is None:
        questiony = input("....")
        if y == "SomethingWrongabout questionY":
            print ("Something went wrong.")
            y = None
            continue

        other codes...

    if z is None:
        questionz = input("....")
        if z == "SomethingWrongabout questionZ":
           print ("Something went wrong.")
            z = None
           continue

        other codes..  

答案 8 :(得分:1)

问题在于程序凝聚力。如果您有特定问题的特定问题,您应该为它们编写函数。

def getX():
   while True:
      response = input("...")
      if response == "something wrong with x":
         print("Something went wrong with x")
      else:
         return response

def getY():
   ...

然后在您的代码中

x = getX()
y = getY()
z = getZ()

这些功能中的每一个都可以以不同方式验证输入。如果您的许多验证都属于特定模式,您也可以尝试概括它们。 E.g。

def getInt(name, range_start, range_end):
   prompt = "Enter a number for {} between {} and {}".format(name,
                                                             range_start, 
                                                             range_end)
   while True:
      try:
          response = int(input(prompt))
      raise ValueError:
          print("That's not a number")
          continue
      if response not in range(range_start, range_end+1):
          print(response, 'is not in the range')
      else:
          return response

答案 9 :(得分:1)

问题的一个简单解决方案是使用计数器变量来解决问题。这样的事情:

counter = 0
while True:
    if counter == 0:
        questionx = input("....")
        if x =="SomethingWrongabout questionX":
            print ("Something went wrong.")
            continue
        else:
            counter = counter + 1
         other codes...

    if counter <= 1:
        questiony = input("....")
        if y == "SomethingWrongabout questionY":
            print ("Something went wrong.")
            continue
        else:
            counter = counter + 1
        other codes...

    if counter <= 2:
         questionz = input("....")
         if z == "SomethingWrongabout questionZ":
             print ("Something went wrong.")
             continue
         else:
             counter = counter + 1
        other codes..

这个想法是每当有正确的事情增加计数器。计数器递增后,它将不会执行其他条件,并将直接跳转到出错的代码块

答案 10 :(得分:1)

我这样做:

qa = (
    ('Question X', 'Answer X'),
    ('Question Y', 'Answer Y'),
    ('Question Z', 'Answer Z'),
)

for item in enumerate(qa):
    question = item[1][0]
    answer = item[1][1]
    while True:
        usr = input("What is the answer to %s: " % question)
        if usr == answer:
            break

结果是:

$ python qa.py
What is the answer to Question X: Answer X
What is the answer to Question Y: Answer Y
What is the answer to Question Z: Answer X
What is the answer to Question Z: Answer Z

Process finished with exit code 0