如何通过用户输入在Python 3中创建无限嵌套字典

时间:2019-01-09 05:54:55

标签: python python-3.x dictionary nested

我目前正在上我的第一门Python课程,并且没有CS的背景知识。我正在研究一个假想程序,该程序将讨论主题和批判性思维作业中的小问题合并在一起,以便以对我来说有意义的方式练习使用代码(我是一名公关人员和摄影师)。目前,该程序是供公关人员使用的客户数据库,用于添加客户信息,打印完整的客户列表以及计算预扣税。

我正在努力创建通过用户输入填充的无限嵌套字典。我已经在网上搜索过,但找不到符合我的假设要求的解决方案。

对于程序的“ ADD”分支,我希望能够将新的客户端/信息添加到嵌套字典(client_info)中。该程序向用户询问一系列问题,例如客户ID,乐队名称,合同结束日期,薪水和管理。我希望使用某种循环,以便用户可以在client_info词典中添加一堆乐队,并且该程序将自动更新并为client_info词典中的每个乐队创建一个新的词典。

我首先用四个波段及其信息填充client_info。然后,我创建了空字典(为每个空字典分配了数字)并为每个空字典编写了单独的代码(共10个),但这意味着我有很多代码,而且我想不出一种方法来回收代码简化程序。

我也尝试过使用乐队的缩写,而不是一个数字,以为分配客户ID可能是一种简单的方法,但是不幸的是失败了,我找不到使程序运行的方法。

# Define dictionary for client information
client_info = {1: {'band' : 'colfax_speed_queen','email' :  'csq@colfaxspeedqueen.com', 'contract' : '20190808', 'pay' : int(800), 'mgmt' : 'MGI'},
         2: {'band' : 'the_ghoulies', 'email' : 'tg@theghoulies.com', 'contract' : '20191031', 'pay' : int(250), 'mgmt' : 'DIY'},
         3: {'band' : 'hail_satan', 'email' : 'hs@hailsatan.com', 'contract' : '20190606', 'pay' : int(700), 'mgmt' : 'APG'},
         4: {'band' : 'plastic_daggers', 'email' : 'pd@plasticdaggers.com', 'contract' : '20190420', 'pay' : int(1000), 'mgmt' : 'DIY'}}

# Pretend to create infinite nested dictionary for client information, but ultimately fail
c = 4
while c <= 19:
    c += 1
    client_info[c] = {}

# General greeting
print("Welcome to the client database.")

# Directions to use database
main_menu = str("""You can:
    PRINT your client list.
    ADD a new client to the database.
    Calculate your TAX withholding.""")
print(main_menu, "\nWhat would you like to do?")
access_client = input()

# Add client to database
elif access_client.lower() == 'add':

    while access_client.lower() == 'add':

        # Request user input for client id
        print("\nWhat is the client id?")

        # Update client id
        c = int(input())

        # Request user input for client_info[c]['band']
        print("What is the name of the band?")

        # Update client_info[c]['band']
        client_info[c]['band'] = input()

        # Request user input for client_info[c]['email']
        print("What is " + client_info[c]['band'] + "\'s email address?")

        # Update client_info[c]['email']
        client_info[c]['email'] = input()

        # Request user input for client_info[c]['contract']
        print("When does " + client_info[c]['band'] + "\'s contract end?")

        # Update client_info[c]['contract']
        client_info[c]['contract'] = int(input())

        # Request user input for client_info[c]['pay']
        print("What is your payment from " + client_info[c]['band'] + "?")

        # Update client_info[c]['pay']
        client_info[c]['pay'] = int(input())

        # Request user input for client_info[c]['mgmt']
        print("Who is managing " + client_info[c]['band'] + "?")

        # Update client_info[c]['mgmt']
        client_info[c]['mgmt'] = input()

        # Notify user that system has been updated with client information
        print("\nThank you for adding " + client_info[c]['band'] + "\'s information to the client database. The database has been updated.")
        print(client_info[c])
        print(client_info)

        # Ask user to add another client
        print("\nType ADD to add another client. Hit any other key to return to the main menu.")
        add_client = input()
        if add_client.lower() != 'add':
            break
    print(main_menu)

while c <= 19循环以我想要的方式工作,但是如果用户不知道最后一个客户ID号,他们可能会意外覆盖以前的条目。 如果您打印完整的词典,那么到20的所有空白词典也将被打印。如果我想选择在词典中包含200个条目,那么当我想查看完整的客户列表时,将所有这些空白词典打印出来会很烦人。 由于我当前在字典中有4个条目,因此必须在while c <= 19循环之上设置c = 4。 (目前我们还没有讨论如何保存用户输入的内容,但是我假设一旦我知道如何保存就将成为问题。)我每次需要更新c =#使用了程序。如果我使用c = 0,它将删除我已经保存在字典中的条目。

我认为我已经接近了,但是效率不如我希望的那样。我将不胜感激,因为您完全是菜鸟,也不知道我在做什么,您可以给我任何帮助! 谢谢!

2 个答案:

答案 0 :(得分:0)

与其为尚未输入客户的空字典预填充顶级字典,不如在收集有关新客户的信息之前,根据需要创建每个字典。

您的程序可以自动计算新的客户ID号,使用len(client_info)len(client_info) + 1之类的方法根据您已有的记录数来获取新的ID。这是一个非常简单的示例,其中的客户记录大大简化了:

client_info = {} # start empty

while True:
    new_client = {}
    name = input("what is the band's name? ")
    new_client['name'] = name
    new_client_id = len(client_info) # starts at zero, add 1 if you want the IDs to start at 1
    client_info[new_client_id] = new_client

    print("client added, client_info is now", client_info)

如果您从不从中删除客户端,则也可以考虑使用列表作为数据结构的顶层。您只需生成记录append到客户列表,而不是生成ID并为其建立索引以分配新的客户记录。该ID将是隐式的,因为客户端在列表中所处的位置。

答案 1 :(得分:0)

您可以考虑使用以下原始示例进行操作:

ids = client_info.keys()
next_c = max(ids) + 1

fields = ['band', 'email', 'contract', 'pay', 'mgmt']

for field in fields:
    print("Enter ", field)
    client_info[next_c][field] = input()

基本思想是找到下一个用作id的c,以寻找最大实际id + 1。 这样可以避免使用已经使用过的ID,但是如果删除了最后一个ID,则不能使用。为了避免重用已经使用的ID而不是删除对象,请将其设置为None(例如):

client_info = {1: None, .....}

声明您需要在列表中填充的字段,以便您可以在其上迭代广告保持代码DRY。


这只是进一步定制的起点。 例如,自定义答案:

fields_2 = {'band': 'What is the name of the band?', 'email': 'What is the band email address?', 'contract':'When does contract ends?', 'pay':'What is your payment from the band?', 'mgmt':'Who is managing the band'}
for field, answer in fields_2.items():
    print(answer)
    # client_info[next_c][field] = input()

因此,用户可以看到:

# What is the name of the band?
# What is the band email address?
# When does contract ends?
# What is your payment from the band?
# Who is managing the band?