8

我有一张表格:

A1, B1, C1, (value)
A1, B1, C1, (value)
A1, B1, C2, (value)
A1, B2, C1, (value)
A1, B2, C1, (value)
A1, B2, C2, (value)
A1, B2, C2, (value)
A2, B1, C1, (value)
A2, B1, C1, (value)
A2, B1, C2, (value)
A2, B1, C2, (value)
A2, B2, C1, (value)
A2, B2, C1, (value)
A2, B2, C2, (value)
A2, B2, C2, (value)

我想在 python 中使用它作为字典,形式为:

H = {
    'A1':{
        'B1':{
            'C1':[],'C2':[],'C3':[] },
        'B2':{
            'C1':[],'C2':[],'C3':[] },
        'B3':{
            'C1':[],'C2':[],'C3':[] }
    },
    'A2':{
        'B1':{
            'C1':[],'C2':[],'C3':[] },
        'B2':{
            'C1':[],'C2':[],'C3':[] },
        'B3':{
            'C1':[],'C2':[],'C3':[] }
    }
}

这样就H[A][B][C]产生了一个特定的唯一值列表。对于小型字典,我可能只是像上面那样提前定义结构,但我正在寻找一种有效的方法来遍历表并构建字典,而无需提前指定字典键。

4

5 回答 5

12
input = [('A1', 'B1', 'C1', 'Value'), (...)]

from collections import defaultdict

tree = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
#Alternatively you could use partial() rather than lambda:
#tree = defaultdict(partial(defaultdict, partial(defaultdict, list)))

for x, y, z, value in input:
    tree[x][y][z].append(value)
于 2012-04-17T14:35:25.293 回答
4

如果您只访问 H[A][B][C] (也就是说,永远不会单独访问 H[A] oder H[A][B]),我建议使用 IMO 更清洁的解决方案:使用元组作为 defaultdict 索引:

from collections import defaultdict
h = defaultdict(list)
for a, b, c, value in input:
    h[a, b, c].append(value)
于 2012-04-17T14:48:22.197 回答
2
d = {}
for (a, b, c, value) in your_table_of_tuples:
   d.setdefault(a, {}).setdefault(b,{}).setdefault(c,[]).append(value)
于 2012-04-17T14:37:28.250 回答
1

这适用于任意数量的键:

def parse_table_to_tree(table):
    tree = dict()
    for row in table:
        tree = attach_leaf(tree, row[:-1], row[-1])
    return tree


def attach_leaf(tree:dict, keys:list, value):
    d = tree
    for i, key in enumerate(keys):
        if i < len(keys)-1:
            d = d.setdefault(key, {})
        else:
            d[key] = value
    return tree

tree = parse_table_to_tree(
    [
        ['a', 'b', 'c', []],
        ['a', 'b', 'd', []],
        ['a', 'f', 'a', []]
    ]
)
于 2020-11-10T07:44:38.693 回答
0

但是,如果您没有三个级别,而是可能有十个级别怎么办?很确定你可以用一个while循环来做到这一点,但这就是我想出的(警告:对可变性和指针的极端利用)

def build_tree(data, categories):
    """Build a dependency tree based on a Pandas DataFrame and an
    ordered list of levels.

    Parameters
    ----------
    data : pandas.core.frame.DataFrame
        A DataFrame containing the table to derive tree from
    categories : array_like
        An ordered, sliceable list of column names to include in tree

    Returns
    -------
    hierarchy : dict
        A standard Python dictionary
        """
    hierarchy = {}
    def expand(data, categories, current_level):
        if len(categories) == 2:
            for value in data[categories[0]].unique():
                current_level[value] = data.loc[data[categories[0]] == value, categories[1]]
        else:
            for value in data[categories[0]].unique():
                current_level[value] = {e: None for e in data.loc[data[categories[0]] == value, categories[1]].unique()}
                expand(data.loc[data[categories[0]] == value, :], categories[1:], current_level[value])
    expand(data, categories, hierarchy)
    return hierarchy

我觉得一些 for 循环可能会更好,但不是总是这样吗?

这也取决于在您的层次结构底部找到的单个键/值对。

于 2019-08-08T11:14:44.700 回答