根据包含键的列表访问 defaultdict(dict)

Access defaultdict(dict) based on list containing the keys

好的,我正在处理一个项目,但我无法解决这个问题。 如果之前有人问过这个问题,我深表歉意,我已经搜索过但一无所获。 这是我的第一个 post.

我有一些 pandas 数据帧,我想根据我设置的哈希访问这些数据帧:

df = defaultdict(lambda: defaultdict(dict))
or
df = defaultdict(dict)

我这样做是为了根据用例像 df['a']['1'][1]df['a'][1] 那样建立索引。 请注意,“矩阵”的形状不一定相等。所以 df['a']['2'][1] 可能存在,但 df['b']['2'][1] 不存在。

TLDR

我想使用 ['a', '2', 1] 或 ['a', 1]

之类的列表访问 df

我做了什么:

旧方法:

我过去常常创建主列表,然后我会遍历并检查。这行得通,但我觉得它很难看。对于上面的两个用例,它也是不同的。我现在正尝试围绕上述两个用例制作一个包装器。我希望包装器不要成为这两个用例的大开关。

x_master_list = []
y_master_list = []
for x in df:
   if x not in x_master_list:
       x_master_list.append(channel)
   for y in df[x]:
       if y not in y_master_list:
           y_master_list.append(idx)

for y in y_master_list:
        for x in x_master_list:
            if x in df:
                if y in df[x]:

较新的方式:

我发现 讨论使用递归来获取所有密钥。这很好,因为它保留了层次结构的顺序。

def iter_leafs(d, keys=[]):
    for key, val in d.items():
        if isinstance(val, defaultdict) | isinstance(val, dict):
            yield from iter_leafs(val, keys + [key])
        else:
            yield keys + [key]

我将主列表的创建修改为:

def create_master_lists(type, df):
    check_type(type)
    lists = master_lists[type]
    key_list = list(iter_leafs(df))
    for key in key_list:
        for idx,list in enumerate(lists):
            if key[idx] not in list:
                list.append(key[idx])
    return lists

现在我想做如下事情:

key_list = list(iter_leafs(df))
for y in y_master_list:
        valid_idx_keys = [key for key in keylist if key[-1] == y]

这里 key_list 看起来像 [['a','1',0],['a','1',1], etc] valid_idx_keys 基本上是过滤后的版本。

我想从 valid_idx_keys 中获取每个列表并访问 df。我不知道如何实现这一目标。

如果我执行以下操作,它会起作用,但重点还是要围绕两个没有相同数量索引参数的用例进行包装。

for x,y,z in valid_idx_keys:
    df[x][y][z] 

也许有一些递归的东西,可以为子列表中的每个元素慢慢地降低一层?我仍在尝试,但我想 post 以防万一有人有办法实现此目标或更好地解决我的问题。

所以我得到了以下结果。它有效,但我愿意接受建议。

from collections import defaultdict

def search_dict(d, list):
    key = list[0]
    val = d.get(key)
    if isinstance(val, defaultdict) | isinstance(val, dict):
        yield from search_dict(val, list[1:])
    else:
        yield val

df = defaultdict(lambda: defaultdict(dict))
df['a']['1'][1] = 0
df['b']['1'][1] = 1

test_key_list = [['a', '1', 1], ['b','1',1]]

print(list(search_dict(df, test_key_list[0])))
print(list(search_dict(df, test_key_list[1])))

vals = []
for lis in test_key_list:
    print(lis)
    vals = vals + list(search_dict(df, lis))
print(vals)

df2 = defaultdict(dict)
df2['a'][1] = 0
df2['b'][1] = 1

test_key_list2 = [['a', 1], ['b',1]]

vals = []
for lis in test_key_list2:
    print(lis)
    vals = vals + list(search_dict(df2, lis))
print(vals)