【问题标题】:Having issues with python nested dictionariespython嵌套字典有问题
【发布时间】:2017-08-23 08:04:08
【问题描述】:

我在 python 方面遇到了一些新手问题,尽管我在网上看到了所有建议,但我无法访问我正在尝试访问的列出的字典中的值。

这是 API 返回的数据:

OrderedDict([(u'totalSize', 1), (u'done', True), (u'records', [OrderedDict([(u'attributes', OrderedDict([(u'type', u'Contact'), (u'url', u'/services/data/v29.0/sobjects/Contact/00346000004eV89AAE')])), (u'Name', u'This is my name')])])])

这是我最近的尝试:

dict['records']['Name']

    print(dict['records']['Name'])
TypeError: list indices must be integers, not str

任何帮助将不胜感激

【问题讨论】:

  • dict['records'] 是有序字典的 list,正如错误消息告诉您的那样。此外,dict 对字典来说是个坏名字,因为它会影响内置字典。
  • 我认为您期望字典是嵌套的,但正如您从运行type(dict['records']) 中看到的那样,您实际上创建了一个子列表,而不是字典。此外,最好不要使用 dict 作为字典的名称,因为这也是一个 python 类。它可能会让人感到困惑。

标签: python-2.7


【解决方案1】:

您从 API 获得的数据结构有一个字典列表,为 dict['records']。你似乎在期待一本字典。

由于列表只有一个元素,您可能只需要索引列表即可获得所需的值:dict['records'][0]['name']

但是,如果列表中可能有不同数量的内部字典,您可能需要编写列表推导式(或显式循环)。试试[inner['name'] for inner in dict['records']] 之类的东西。这将为您提供一个名称列表,其中包含与dict['records'] 列表相同数量的项目。

请注意,在代码中使用dict 作为变量名可能是个坏主意,因为这是内置字典类型的名称。将它用于其他内容可能会导致以后代码中出现意外错误(当您想要创建字典但最终调用其他内容时)。这不是您索引数据结构问题的原因,只是稍微改进代码的一种方法。

【讨论】:

  • 非常感谢。我非常感谢您的解释,并且效果很好。我通常不会将字典命名为“dict”,但我只是在展示我的问题示例时这样做了。我没有意识到它可能会产生问题,谢谢。我一定会确保我以后不会这样做。
【解决方案2】:

你只需要删除嵌套的OrderedDict周围的括号,所以

OrderedDict([..., (u'records', OrderedDict([...]))])

而不是

OrderedDict([..., (u'records', [OrderedDict([...])])])

这是因为OrderedDict 期望它的参数是一个键值对列表。在您的代码中,键 'records' 的值是一个包含单个字典的列表。你希望它只是一本字典。

编辑:由于您无法更改用于构建字典的数据,因此有几种解决方法。

解决方法 #1

忍受更烦人的调用方案:

d['records'][0]['Name']

这是更简单的解决方法,但当然它很难看,也更难理解。

解决方法 #2

OrderedDict 包装在自定义项目访问语法的新类中。

class MyOrderedDict(OrderedDict):
    def __getitem__(self, key):
        ret = super().__getitem__(key)
        if isinstance(ret, list):
            if ret and isinstance(ret[0], OrderedDict):
                return ret[0]
        return ret

这使得如果像d['records']这样的调用的返回值是一个列表,其第一个元素是OrderedDict,那么OrderedDict将被返回而不是列表,这样你就可以链接项访问。你可以这样写:

d = MyOrderedDict(api_data)
d['records']['Name'] # 'This is my name'

【讨论】:

  • 谢谢。我忘了提到嵌套字典是 API 返回的输出,所以我无法真正修改 API 发送数据的方式。
  • 非常感谢:)。这很完美。我将使用 #1 作为短期解决方案,但我会确保在我坐下来弄清楚之后实施 #2。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 2017-01-20
  • 2018-08-21
相关资源
最近更新 更多