【问题标题】:Python3: TypeError: list indices must be integers or slices, not strPython3:TypeError:列表索引必须是整数或切片,而不是 str
【发布时间】:2018-10-13 22:33:34
【问题描述】:

我的数据以 json 格式存储。通过使用 json:load() 我正在读取数据。

我要做的是基于传递的参数,我试图从列表中提取 Key:Value 的特定部分并将它们存储到一个新列表中以供以后处理。

代码

selected_env='mydev2'
server_list=[{'mydev': ['192.168.56.102', '192.168.56.102', '192.168.56.102']}, {'mydev2': ['192.168.56.102', '192.168.56.102', '192.168.56.102']}]         
for item in server_list :
    host_list=[item for item in server_list[selected_env] if selected_env in server_list]

print(host_list)

我收到错误

TypeError: list indices must be integers or slices, not str

注意:我已经实现了如下一种提取方式

for item in server_list:
  for element in item :
    if element == selected_env :
       host_list=item[selected_env]  

尽管它可以工作,但我还是想优化它,并阅读了一些关于列表提取的文章,并遇到了上述错误。

任何帮助,不胜感激。

【问题讨论】:

    标签: python python-3.x list


    【解决方案1】:

    当一个简单的字典可以工作时,为什么要使用一个字典列表???

    servers={
       'mydev': ['192.168.56.102', '192.168.56.102', '192.168.56.102'], 
       'mydev2': ['192.168.56.102', '192.168.56.102', '192.168.56.102'],
       }
    
    host_list = servers["mydev2"]
    

    字典查找是 O(1) 并且非常优化(字典在 Python 内部无处不在)。列表查找是 O(N)。

    【讨论】:

    • 啊!没有服务器不是我创建的。我正在从 json 文件中提取它。所以我觉得您的解决方案不适用于我的情况,但感谢您抽出宝贵时间。
    【解决方案2】:

    你做错了什么是你通过selected_env访问列表server_list中的元素,这是一个字符串。

    server_list[selected_env]
    

    上述陈述导致您的错误。相反,您需要检查 selected_env 是否在 itemserver_list 中。

    这应该可行:

    selected_env='mydev2'
    server_list=[{'mydev': ['192.168.56.102', '192.168.56.102', '192.168.56.102']}, {'mydev2': ['192.168.56.102', '192.168.56.102', '192.168.56.102']}]         
    for item in server_list :
        host_list = [item[selected_env] for item in server_list if selected_env in item]
    host_list = list(itertools.chain(*host_list)) # To convert sub-list into flat
    # assumed as import itertools included    
    
    print(host_list)
    # [['192.168.56.102', '192.168.56.102', '192.168.56.102']]                                                
    

    【讨论】:

    • 啊!谢谢你指出我的错误。但我只需要列出作为输出,但通过你的回答它显示为 dict 所以我必须再次通过host_list[selected_env]。谢谢。
    • 很抱歉。我误解了你的输出。现在更新了 sn-p。
    • 感谢您添加答案。我已经接受了另一个答案,并且已经对你的答案投了赞成票(感觉现在做不了太多)。但是您的解决方案看起来也很简洁,在处理大型数据集时,我觉得您的解决方案需要更少的 CPU 周期,因为您没有进行任何转换
    • 没关系。:) 但请记住,如果您在 server_list 中还有一个 selected_env 条目,则另一个答案不会找到该条目。
    • 啊!你的意思是 server_list[] 中的 mydev3 ?
    【解决方案3】:

    如果您的输入数据必须是字典列表,我建议您首先将其转换为单个字典,使用良好的字典理解,如下所示:

    selected_env='mydev2'
    server_list=[{'mydev': ['192.168.56.101', '192.168.56.102', '192.168.56.103']}, {'mydev2': ['192.168.56.104', '192.168.56.105', '192.168.56.106']}] 
    
    server_dict = {k:v for d in server_list for k,v in d.items()}
    host_list = server_dict[selected_env]
    
    print(host_list)
    

    注意:
    d.items() 返回一个列表,其中包含字典 @​​987654323@ 的所有元组(键、值)。
    所以对于我的代码,在字典理解中:

    1. 在第一次迭代中,d 等于 {'mydev': ['192.168.56.101', '192.168.56.102', '192.168.56.103']}d.items() 等于 [('mydev',['192.168.56.101', '192.168.56.102', '192.168.56.103'])]

    2. 在第二次迭代中,d 等于 {'mydev2': ['192.168.56.104', '192.168.56.105', '192.168.56.106']}d.items() 等于 [('mydev2',['192.168.56.104', '192.168.56.105', '192.168.56.106'])]

    【讨论】:

    • 谢谢,看来我可以使用这个解决方案。您介意添加一些关于 d.item() 的内容吗?
    • 不客气。我更新了我的帖子,添加了关于 d.items() 的更多解释
    猜你喜欢
    • 1970-01-01
    • 2017-11-08
    • 2015-12-09
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多