【问题标题】:How to fix "TypeError" - 'dict_keys' object is not subscriptable?如何修复“TypeError” - 'dict_keys' 对象不可下标?
【发布时间】:2020-01-30 16:38:38
【问题描述】:

我对 Python 完全陌生,我只是在练习和“复制”一些 github 代码。这样做时,我意识到我使用的是最新版本的 Python,而视频中的那个人使用的是 Python 2.7,所以他使用的代码与我的不兼容。请帮助我如何重写代码。

def add_friend(self,friend_id):
    check_req = requests.get('https://gift-f06e4.firebaseio.com/.json?orderBy="my_friend_id"&equalTo=' + friend_id)

    data = check_req.json()
    print(check_req.ok)
    print(check_req.json())
    if data == {}:
        self.root.ids['add_friend_screen'].ids['add_friend_label'].text = "Invalid friend ID"

    else:
        key = data.keys()[0]
        new_friend_id = data[key]['my_friend_id']
        print('New friend id is', new_friend_id)

问题出现在这一行:

key = data.keys()[0]

我知道这不是我应该在 Python 3 中编写这部分的方式,但我不知道如何使它工作。

【问题讨论】:

  • key = next(data.keys())
  • 谢谢!试过了,但仍然发生 TypeError:'dict_keys' 对象不是迭代器。尽管我尝试使用 key = list(data.keys()) 并且它有效。 next 和 list 有什么区别?

标签: python typeerror


【解决方案1】:

tl;dr: 如果字典中只有一个元素,那么使用list(data.keys())[0] 就可以了。如果您有多个元素,那么答案是:“这取决于...”(因为您将随机获得一个元素)。

编辑:Python 3.7 的附加细节:字典排序已成为确定性,这一事实已成为语言规范的一部分,因此您可以在 Python 中依赖此。早期版本的 Python 可能已经是确定性的,但这是特定于实现的,而不是规范的一部分,因此您不应该依赖它。最后,虽然这对于 Python 3.7+ 是正确的,但对于其他编程语言则不一定如此,因此您需要小心养成这种习惯。


对于这个特定的用例,您将其转换为列表的解决方案对我来说似乎很好。

我只是想离题一下为什么这是不可订阅的原因,这可能会导致您不依赖[0]而使用另一种解决方案。

nb:查看从 HTTP GET 调用返回的 JSON 文档示例有助于做出更明智的陈述。我将继续进行明智的猜测:

从代码中,我可以肯定地说,GET 调用的结果是一个 JSON 文档,其中包含一个对象(换句话说:被 {} 包围的东西)。调用.json() 方法时,这将转换为 Python 字典。

Python 字典没有保证键的顺序。所以这两个实例被认为是相同的(即使顺序不同),您可以在 Python 控制台中尝试:

>>> a = {"a": 10, "b": 20}
>>> b = {"b": 20, "a": 10}
>>> a == b
True

在您的代码中,您使用data.keys()[0],这意味着:“给我字典的第一个键”。但是因为不能保证订购,所以要求“第一个”项目并没有真正的意义。 这就是为什么在 Python 3 中它不再是可下标的。他们禁止它以防止代码中的逻辑错误。

作为旁注,我应该说,从 Python 3.7 开始,Python 字典中的排序在某些条件下是稳定的,但您仍然不应该依赖这种行为。

如果您 100% 确定您使用的字典只有一个元素,那么转换为列表并获取第一个元素是完全安全的。如果字典中只有一个元素,或者使用@rdas 提到的next() 也可以。如果字典有多个元素,则不能保证每次调用都为您提供相同的元素,您只会从中获得“任何一个”元素。

此外,如果您可以控制 JSON 结构,则可以决定是否要将项目作为字典或列表返回。后者将有保证的顺序。

如果您可以使用示例 JSON 文档编辑您的问题,我可以提供更多信息。

【讨论】:

  • 对于现在阅读本文的任何人,从 Python 3.7 开始,字典是有序的
【解决方案2】:

好的,我刚刚让它工作了:我尝试了key = list(data.keys())[0],而不是key = data.keys()[0],它似乎工作正常。

仍然不确定这是否是正确的方法。 我会接受任何建议,建议,帮助。 非常感谢!

【讨论】:

    猜你喜欢
    • 2020-02-10
    • 2014-12-11
    • 2016-08-20
    • 1970-01-01
    • 2019-09-27
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多