简体   繁体   English

如何在Python中动态构建字典

[英]how to dynamically build a dictionary in Python

i want to dynamically build a dictionary in python. 我想在python中动态建立字典。 based upon a set of shows that has one dimension. 基于一组具有一个维度的表演。

this is what i have currently do when looping through the entries 这是我当前遍历条目时所做的

class Show(object):
    def __init__(self, json_data):
        self.name = json_data.get("abstract_name")
        self.id = json_data.get("abstract_key")
        self.station = json_data.get("station")
        self.first_letter = json_data.get("first_letter")


    def to_dict(self):
        return self.__dict__


 shows = {} 
 for entry in json.get("material"):
        show = Show(entry)
        first_letter = show.first_letter

        if shows.get(first_letter, None) is None:
            shows.update(first_letter, {})

        if shows.get(first_letter).get(show.id, None) is None:
            shows.get(first_letter).update(show.id, {})

        shows.get(first_letter).get(show.id).update(show.to_dict())

What i want to do is create the indexes where it is empty. 我想做的是在空的地方创建索引。 But i can't seem to find a way to do this 但是我似乎找不到办法

First, you're not using dict.update() the right way. 首先,您没有正确使用dict.update() dict.update() expects either: dict.update()期望:

1/ a dict (or dict-like) object 1 /一个字典(或类似字典的对象)

d.update({"foo":"bar"})

2/ a sequence (list or any iterable) of (key, value) pairs 2 / (key, value)对的序列(列表或任何可迭代)

d.update([("foo", "bar")])

3/ keyword args 3 /关键字参数

d.update(foo="bar")

Note that all those three examples could be written much more simply as 请注意,所有这三个示例可以更简单地写为

d["foo"] = "bar"

dict.update() is mostly useful if you want to set many keys at once and/or already have another dict or a sequence of key,value pairs. 如果您想一次设置多个键和/或已经具有另一个dict或键,值对序列,则dict.update()最有用。

Also, you don't have to .get() a key to test if it's already set, you can test for containment with key in yourdict (negating it with key not in yourdict ) ie: 另外,您不必.get()来测试是否已设置key in yourdict ,您可以key in yourdict使用key in yourdict来测试是否包含(与key in yourdict使用key not in yourdict否定),即:

if first_letter not in shows:
    shows[first_letter] = {}

But in your case, the simplest solution is to use a defaultdict : 但是在您的情况下,最简单的解决方案是使用defaultdict

from collections import defaultdict

# we want a defaultdict of defauldicts of dicts,
# so we need a custom factory function
def defaultdict_of_dicts():
    return defaultdict(dict)

shows = defaultdict(defaultdict_of_dicts)

for entry in json.get("material"):
    show = Show(entry)
    shows[show.first_letter][show.id].update(show.to_dict())             

As a last note: your show.to_dict() method may have unwanted side effects: 最后一点:您的show.to_dict()方法可能会有不良的副作用:

>>> s = Show({"abstract_name":"name", "abstract_key": "key", "station":"station", "first_letter":"first_letter"}) 
>>> s.first_letter
'first_letter'
>>> d = s.to_dict()
>>> d
{'first_letter': 'first_letter', 'station': 'station', 'name': 'name', 'id': 'key'}
>>> d["first_letter"] = "gotcha"
>>> s.first_letter
'gotcha'
>>> 

It would be safer to implement to_dict() as return self.__dict__.copy() (well, might not be that important in this exact example, but better safe than sorry...) to_dict()作为return self.__dict__.copy()实现会更安全(嗯,在这个确切的示例中可能并不那么重要,但是比对不起更安全...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM