在Python中按键分割字典

-8 投票
1 回答
2261 浏览
提问于 2025-04-19 10:22

我想对这段代码做个解释,特别是关于变量的部分。我是个python新手。

目标:
我想根据字典pairs中的keys来拆分这个数据字典。输出应该是一个包含Ward类的列表的列表。我觉得我的解决方案有点复杂,不知道有没有更好的方法?

class Ward:
    def __init__(self, code, data):
        self.code = code
        self.data = data


def prepare_data_for_templates(cs, h, f):       
    pairs = {'201': ['<tr><td>Dunajsk&#225; Streda</td><td>201</td></tr>\n', '<tr><td>Dunajsk&#253; Kl&#225;tov</td><td>201</td></tr>\n'], '205': ['<tr><td>Ko&#353;oln&#225;</td><td>205</td></tr>\n',]}

    print "Pairs: " + str(sorted(pairs.keys())) + "\n"

    #output data - ba, tt...
    OUT = []

    BA = []
    TT = []

    for k, v in sorted(pairs.iteritems()):
        #print k + "\n", v
        if int(k) < 199:
            BA.append( Ward(k, v )
        elif int(k) < 299:
            TT.append( Ward(k, v )

    OUT.append(BA)
    OUT.append(TT)


    for j in OUT:
        for i in j:
            print i.code

    return OUT

编辑:感谢你的回答,我更新了我的代码,使用了JSON。

tab01.json:

{
    "data": [
        {
            "id": "101", "c01": "mun1"
        },
        {
            "id": "101", "c01": "mun2"
        },
        {
            "id": "205", "c01": "mun3"
        },
        {
            "id": "205", "c01": "mun4"
        },
        {
            "id": "205", "c01": "mun5"
        }
    ]
}

code.py:

import os, json

def prepare_data_for_templates(file):       

    pairs = {}
    codes = []

    with open(file, "r") as input:
        json_obj = json.load(input)

    for d in json_obj["data"]:
        codes.append((str(d["id"]), d))

    for c in codes:
        pairs.setdefault(str(c[0]), []).append(c[1])

    for k, v in pairs.iteritems():
        with open( str(k) + '.json', 'w') as outfile:
            json.dump(v, outfile)

prepare_data_for_templates("tab01.json")

1 个回答

0

“清理这段(可用的)代码”通常不是一个好的StackOverflow问题,因为它太模糊了。我给这个问题投了反对票,但在这个特定的情况下,有一些事情可以立刻改进。


使用新风格的类或元组

你的 Ward 类看起来是多余的。除非你有其他功能没有展示出来,否则你可以直接使用元组。与其写 Ward(k, v),不如直接用元组 (k, v)

如果你确实需要这个类,至少要把它写成新风格的类,像这样:class Ward(object):。你现在用的语法 class Ward: 已经过时了,只是为了历史原因还在支持。

将数据与代码分开

现在,你有一个巨大的、混乱的、难以处理的变量,

pairs = {'201': ['<tr><td>Dunajsk&#225; Streda</td><td>201</td></tr>\n', '<tr><td>Dunajsk&#253; Kl&#225;tov</td><td>201</td></tr>\n'], '205': ['<tr><td>Ko&#353;oln&#225;</td><td>205</td></tr>\n', '<tr><td>Leopoldov</td><td>205</td></tr>\n', '<tr><td>Trnava</td><td>205</td></tr>\n'], '705': ['<tr><td>Pu&#353;ovce</td><td>705</td></tr>\n', '<tr><td>Radatice</td><td>705</td></tr>\n', '<tr><td>Rokycany</td><td>705</td></tr>\n'], '304': ['<tr><td>Rudnianska Lehota</td><td>304</td></tr>\n', '<tr><td>Sebedra&#382;ie</td><td>304</td></tr>\n', '<tr><td>Se&#269;</td><td>304</td></tr>\n', '<tr><td>&#352;&#250;tovce</td><td>304</td></tr>\n'], '305': ['<tr><td>Selec</td><td>305</td></tr>\n'], '103': ['<tr><td>Modra</td><td>103</td></tr>\n', '<tr><td>Pezinok</td><td>103</td></tr>\n'], '101': ['<tr><td>Bratislava - Nov&#233; Mesto</td><td>101</td></tr>\n', '<tr><td>Bratislava - Podunajsk&#233; Biskupice</td><td>101</td></tr>\n'], '806': ['<tr><td>Plechotice</td><td>806</td></tr>\n', '<tr><td>Trebi&#353;ov</td><td>806</td></tr>\n']}

如果你想添加数据或者数据发生变化,这几乎是无法维护的。这看起来像是某种部分解析的HTML,所以把数据存储成HTML可能更合适,让你的Python代码每次运行时解析HTML。

如果你想保留处理后的数据,而不是原始的HTML源文件,我建议把它放到一个JSON文件里;像这样:

{
  "201": {
    "name": "Dunajsky",
    "municipalities": [
      "Streda",
      "Klatov"
    ]
  },
  "205": {
    "name": "Kosoln",
    "municipalities": {
      "Leopoldov",
      "Trnava"
    }
  }
}

你的数据有点乱,所以这是我对你想表示的结构的最佳猜测。这会让你今后的工作轻松很多。

然后你可以使用Python的 json 库来解析这些数据:

不要使用列表的列表

据我所知,你是在尝试对数据进行排序。为了这个目的,没有必要使用列表的列表——这太复杂了,结果也会让人困惑。

考虑使用更简单的方式,比如这样:

with open('wards.json', 'r') as f:
    json_obj = json.load(f)

# assume the structure above is used for the JSON
# don't do any validation (because that would require more work with something
# like a JSON schema, and I'm too lazy for that)

# convert the object to a list of tuples, and convert codes from strings to ints
code_list = []
for (code, data) in json_obj.items():
    code_list.append((int(code), data))

# sorting tuples does a dictionary-order sorting, so this will sort on keys,
# then on the data components of the tuples (which presumably don't have
# meaningful ordering)
return sorted(code_list)

将数据转换为 code_list 的稍微清晰一点的版本可以使用列表推导:

code_list = [(int(code), data) for (code, data) in json_obj.items()]

撰写回答