【问题标题】:why my menu of dictionary does not appearing?为什么我的字典菜单没有出现?
【发布时间】:2020-08-16 14:50:10
【问题描述】:

我正在尝试为一组路由器显示一个菜单,该菜单由包含有关其状态的信息的字典描述。为此,我有一个函数将包含设备信息的字典routers 作为输入。字典被转换成字典对象列表,称为router_list,使用for循环按设备名称的值排序。所有设备都保存在menu_text变量中,该变量又用于枚举和打印设备。

当我运行这段代码时,我得到了这个错误:

 python3 menu.py 
Traceback (most recent call last):
  File "menu.py", line 28, in <module>
    'password': '2020'
  File "menu.py", line 6, in show_menu
    router_list.append("%s. %s " % ((i+2), value['name'],))
TypeError: string indices must be integers

这是我的代码:

def show_menu(routers):
    router_list = []
    i = 0
    for key, value in enumerate(routers):           
        router_list.append("%s. %s " % ((i+2), value['name'],))
        i = i + 1

    menu_text = '\n'.join(router_list)

    print(("""
---------------------------------------------------------
-----------------------------------------------------

0.EXIT
1.CONFIG ALL
"""+ menu_text +"""
---------------------------------------------------------
          """))

if __name__ == '__main__':
    show_menu({
    'name': 'cisco_ios',
    'ip': '192.168.122.217',
    'username': 'admin',
    'password': '2020'
     })

【问题讨论】:

标签: python json dictionary object


【解决方案1】:

使用enumerate() 循环遍历字典时,您得到的是索引和键,而不是键和值。而且,value['name'] 会导致错误,因为value 不代表字典,它是键(在您的情况下为name、ip 等)。

对于循环键/值对,您可以像这样使用dict.items():

for k, v in dict.items():
    print(k, v)

相关话题:enumerate() for dictionary in python


由于您仅将一个路由器信息作为字典传递,即routers,因此您无需遍历它来提取路由器的名称。

您可以简单地使用routers['name'] 就可以了!

示例 (live):

def show_menu(routers):
    print(("""
---------------------------------------------------------
0.EXIT
1.CONFIG ALL
2."""+ routers['name'] +"""
---------------------------------------------------------
          """))

if __name__ == '__main__':
    show_menu({
    'name': 'cisco_ios',
    'ip': '192.168.122.217',
    'username': 'admin',
    'password': '2020'
     })

输出:

---------------------------------------------------------
0.EXIT
1.CONFIG ALL
2.cisco_ios
---------------------------------------------------------

但是,如果有多个路由器,那么您可以使用表示路由器的字典列表并使用 for 像这样 (live) 循环遍历它:

def show_menu(routers):
    router_list = []
    i = 0
    for router in routers:
        router_list.append("%s. %s " % ((i+2), router['name'],))
        i = i + 1

    menu_text = '\n'.join(router_list)

    print(("""
---------------------------------------------------------
0.EXIT
1.CONFIG ALL
"""+ menu_text +"""
---------------------------------------------------------
          """))

if __name__ == '__main__':
    show_menu([{
        'name': 'cisco_ios',
        'ip': '192.168.122.217',
        'username': 'admin',
        'password': '2020'
     },
     {
        'name': 'cisco_ios_123',
        'ip': '192.168.xxx.xxx',
        'username': 'admin',
        'password': '2021'
     }
     ])

输出:

---------------------------------------------------------
0.EXIT
1.CONFIG ALL
2. cisco_ios 
3. cisco_ios_123 
---------------------------------------------------------

【讨论】:

  • 这是真的,但我必须列举这些字典以供选择
  • @AbdelhakBoumezrag:为什么会这样?你如何得到路由器信息的字典?如果有多个路由器,你会得到什么?一个包含所有路由器的字典?对吗?
【解决方案2】:

您应该将字典列表传递给show_menu(),例如

routers = [
    {
        'name': 'cisco_ios',
        'ip': '192.168.122.217',
        'username': 'admin',
        'password': '2020'
     },
]
show_menu(routers)

原因是,在您的 show_menu() 代码中,您假定 value 是一个字典,因此 routers 的参数应该是一个字典列表。

【讨论】:

  • 是的,您认为这是真的,但实际上我想与另一个功能一起使用,通过从列表菜单中选择一个数字来引用哪个设备来在拓扑上进行一些配置
  • 抱歉回复晚了。我不是很清楚你的需求,但是如果你想用一个数字来选择一个路由器,那么路由器字典列表应该可以工作,因为列表索引可能与路由器编号相同。
猜你喜欢
  • 1970-01-01
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 2013-07-21
  • 2021-07-30
  • 2015-09-04
  • 2013-03-15
  • 2023-03-07
相关资源
最近更新 更多