将具有复合主键的 table 映射到 python 字典

Mapping a table with a compound primary key to a python dictionary

我有一些数据最初看起来像这样,我想在 Python 2.7 中处理它们:

id  year    value
1   2012    5
2   2012    50
3   2012    500
1   2013    6
2   2013    60
3   2013    600
1   2014    7
2   2014    70
3   2014    700

我可以轻松地将其转换成这样的列表[[1,2012,5],[2,2012,6],...]

我想将其转换为字典,因为我想查找固定 id and/or year 的所有不同值(如果这个想法是不太好,我宁愿把它作为一个列表,请在评论中告诉我。)

我知道 python 字典需要一个可散列的键,所以我可以通过将 idyear 连接成一个字符串来转换这个 table 并得到一个字典喜欢

{'1_2012':'5','2_2012':'50', ...} 

显然,如果你想读出键的单独部分,这不是很优雅。获得复合键字典的最简单方法是什么,它仍然很容易 dump 能够进入 json?

您可以使用元组作为键。您可以使用括号创建元组,例如(2,2012) 是一个元组。它们是不可变的,因此可以用作字典键:

d = {(1,2012):5, (2,2012):50}

您可以像索引列表一样索引元组,例如(1,2012)[1]2012.

tuple 可哈希:

{(1, 2012): 5, (2, 2012): 50,}

然而,这个字典不能被dump编辑,这种情况下的字典键应该是一个字符串:

import json
import ast

# Works if keys satisfy following requirement:
# key == ast.literal_eval(repr(key))
# This is true for tuples having numbers inside.

def dumps(d):
    return json.dumps({repr(key): value for key, value in d.items()})

def loads(s):
    d = json.loads(s)
    return {ast.literal_eval(key): value for key, value in d.items()}

在您开始使用足够复杂的键 and/or 并且其 __repr__ 方法实现不佳之前,这对函数应该一直有效。

为此,我建议使用 namedtuple,因为它比标准元组更清晰。

import collections
Key = collections.namedtuple('Key', ['id', 'year'])
data = {Key(id=1, year=2012): 5, Key(id=2, year=2012): 50}