简体   繁体   English

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

[英]Retrieving values from a paired key dictionary in Python

I have the need for a data structure where the keys are essentially a combination of 2 strings. 我需要一个其中键本质上是2个字符串的组合的数据结构。 The overall combination is unique, and the strings are separated by a comma (so a mini csv). 整体组合是唯一的,并且字符串之间用逗号分隔(因此是最小的csv)。 Something like this: 像这样:

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

Now, my question is this. 现在,我的问题是这个。 What is the most optimal way to retrieve all the values given only one part of the pair? 检索仅在一对中给定的所有值的最佳方法是什么? So lets say I give the dictionary ('abc', 1) , the following objects are returned: 因此,可以说我给了字典('abc', 1) ,返回了以下对象:

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

Or if I give the dictionary ('456', 0) , then only the following object is retrieved: 或者,如果我给出字典('456', 0) ,则仅检索以下对象:

[4, 5, 6]

Note, the first argument is the pair of the key, and the second argument is the key index within that pair. 注意,第一个参数是密钥对,第二个参数是该对中的密钥索引。 Is the only way to do this by running a loop through the entire dictionary till all the patterns are found? 做这件事的唯一方法是在整个字典中循环运行,直到找到所有模式为止?

You can create an optimised lookup table by traversing the dictionary once. 您可以遍历字典一次来创建优化的查找表。 Afterwards, you can directly look up partial keys: 之后,您可以直接查找部分键:

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]

This fetches all corresponding values without iteration: 这将获取所有对应的值,而无需迭代:

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

I would suggest making your keys tuples: 我建议使您的键元组:

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

You can retrieve values with a list comprehension: 您可以使用列表理解来检索值:

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

Edit: This answer is kinda the same idea as @MisterMiyagi 's but not as Pythonic, I'm keeping the answer since I have some other stuff that maybe useful for you. 编辑: 这个答案有点像@MisterMiyagi的想法,但是不像Pythonic一样,我保留了答案,因为我还有其他一些可能对您有用的东西。

If you can't modify the paired_dict structure you could preprocess the keys in it to create two more dicts mapping the two partial_keys to the overall_key. 如果您不能修改paired_dict结构,则可以对其中的键进行预处理,以创建更多两个将两个partial_keys映射到overall_key的dict。

Something like this should get you started assuming the paired_dict will always be valid ie the part before the ',' will always be a valid int : 这样的事情会让您开始假设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()

Output: 输出:

('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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM