从Python中的配对键字典中检索值

时间:2019-08-16 21:38:23

标签: python dictionary

我需要一个数据结构,其中的键本质上是2个字符串的组合。整体组合是唯一的,并且字符串之间用逗号分隔(因此是最小的csv)。像这样:

paired_dict = {
    '123,abc': [1, 2, 3],
    '456,abc': [4, 5, 6],
    '123,def': [7, 8, 9],
    ...
}

现在,我的问题是这个。检索仅在一对中给定的所有值的最佳方法是什么?假设我给字典('abc', 1),返回了以下对象:

[1, 2, 3], [4, 5, 6]

或者,如果我给字典('456', 0),则仅检索以下对象:

[4, 5, 6]

请注意,第一个参数是密钥对,第二个参数是该对密钥对。这样做唯一的方法是在整个字典中循环运行,直到找到所有模式为止。

3 个答案:

答案 0 :(得分:2)

您可以遍历字典一次来创建优化的查找表。之后,您可以直接查找部分键:

split_dicts = [{}, {}]
for key, value in paired_dict.items():
    head, tail = key.split(',')
    split_dicts[0].setdefault(head, []).append(value)
    split_dicts[1].setdefault(tail, []).append(value)

def lookup(key, index):
    return split_dicts[index][key]

这将获取所有对应的值而无需迭代:

>>> lookup('abc', 1)
[[1, 2, 3], [4, 5, 6]]
>>> lookup('456', 0)
[[4, 5, 6]]

答案 1 :(得分:1)

我建议将您的键元组设置为

paired_dict = {
    ('123', 'abc'): [1, 2, 3],
    ('456', 'abc'): [4, 5, 6],
    ('123', 'def'): [7, 8, 9],
    ...
}

您可以通过列表理解来检索值:

[v for k, v in paired_dict.items() if k[0] == '456']

答案 2 :(得分:1)

编辑: 这个答案与 @MisterMiyagi 的想法差不多,但不是Pythonic,我一直在回答问题,因为我还有其他一些可能对您有用的东西。

如果您不能修改paired_dict结构,则可以对其中的键进行预处理,以创建另外两个字典,将两个partial_keys映射到total_key。

这样的事情会让您开始假设paired_dict始终有效,即','之前的部分始终是有效的int

from collections import defaultdict

paired_dict = {
    '123,abc': [1, 2, 3],
    '456,abc': [4, 5, 6],
    '123,def': [7, 8, 9],
}

first_key_mappings = defaultdict(list)
second_key_mappings = defaultdict(list)
for key in paired_dict.keys():
    first_key, second_key = key.split(",")
    first_key_mappings[int(first_key)].append(key)
    second_key_mappings[second_key].append(key)


def paired_dict_search(search_term):
    partial_key, index = search_term
    res = []
    if index == 0:
        for key in first_key_mappings[partial_key]:
            res.append(paired_dict[key])
    elif index == 1:
        for key in second_key_mappings[partial_key]:
            res.append(paired_dict[key])
    else:
        raise ValueError(f"Invalid index provided: {index}")
    return res


test_search_terms = [('123', 0), (123, 0), (456, 0), ('abc', 1), ('def', 1),
                     ('123', 3)]
for search_term in test_search_terms:
    print(f"{search_term} => ")
    print(f"\t{paired_dict_search(search_term)}")
    print()

输出:

('123', 0) =>
    []

(123, 0) =>
    [[1, 2, 3], [7, 8, 9]]

(456, 0) =>
    [[4, 5, 6]]

('abc', 1) =>
    [[1, 2, 3], [4, 5, 6]]

('def', 1) =>
    [[7, 8, 9]]

('123', 3) =>
Traceback (most recent call last):
  File "main.py", line 32, in <module>
    print(f"\t{paired_dict_search(search_term)}")
  File "main.py", line 26, in paired_dict_search
    raise ValueError(f"Invalid index provided: {index}")
ValueError: Invalid index provided: 3