首页 > 解决方案 > 如何在 Python 中创建具有固定数量的有效用户条目的字典?

问题描述

我想编写一个 Python 程序来创建一个字典,其中包含用户输入的固定数量的条目。对于每个条目,如果用户输入无效输入,我希望程序提示用户重试,直到他输入有效输入。不幸的是,这个程序不起作用:

phoneBook = {}
numberOfEntries = int(input("Enter number of entries to phone book: "))

for i in range(numberOfEntries):
    try:
        name, phoneNumber = input(
            "Enter details - name, two spaces, phone number: ").split("  ")
        phoneBook[name] = phoneNumber
    except:
        print("Incorrect, two spaces between name and phone number.")
        i -= 1

print(phoneBook)

标签: pythonfor-loopexception

解决方案


i在循环的每次迭代中重新分配for,这会覆盖所有以前的 assignment,包括在 body 中所做的那些,比如你的 assignment i -= 1。因此,请改用while循环。

还有几点建议:

  • 您应该验证所有输入,包括电话簿的条目数。
  • 您应该只捕获最具体的异常(ValueError此处),因此您很少需要捕获所有异常(BaseException)——当您不知道具体要捕获哪些异常时,捕获Exception,而不是捕获BaseException。您的无表达式 except 子句except: 捕获所有异常,因此它等效于 except 子句except BaseException:BaseException捕获(除了ExceptionSystemExitKeyboardInterruptGeneratorExit,您通常不想捕获它们(参见Python 异常层次结构)。
  • 您应该遵循lower_case_with_underscores函数和变量名称的 Python 命名约定,而不是mixedCase(参见PEP 8)。

新程序:

while True:
    try:
        user_input = input("Enter number of entries to phone book: ")
        i = int(user_input)
    except ValueError:
        print("Invalid input, enter a number.")
    else:
        break

phone_book = {}

while i:
    try:
        user_input = input("Enter contact (name, 2 spaces, phone number): ")
        name, phone_number = user_input.split("  ")
    except ValueError:
        print("Invalid input, enter 2 spaces between name and phone number.")
    else:
        phone_book[name] = phone_number
        i -= 1

print(phone_book)

出现一个算法模式,因此您可以创建一个封装它的函数,这样您就不会重复自己(参见DRY 原则):

def prompt(condition, message, warning, validate, process, new):
    output = None
    while condition:
        try:
            user_input = input(message)
            valid_input = validate(user_input)
        except ValueError:
            print(warning)
        else:
            output = process(valid_input)
            condition = new(condition)
    return output


condition = True
message = "Enter number of entries to phone book: "
warning = "Invalid input, enter a number."
validate = lambda x: int(x)
process = lambda x: x
new = lambda x: False
entry_count = prompt(condition, message, warning, validate, process, new)

condition = entry_count
message = "Enter contact (name, 2 spaces, phone number): "
warning = "Invalid input, enter 2 spaces between name and phone number."
validate = lambda x: x.split("  ") if x.index("  ") else None
phone_book = {}
process = lambda x: phone_book.update({x[0]: x[1]})
new = lambda x: x - 1
prompt(condition, message, warning, validate, process, new)

print(phone_book)

推荐阅读