在Python中从成对键字典中检索值

在Python中从成对键字典中检索值,python,dictionary,Python,Dictionary,我需要一个数据结构,其中键基本上是两个字符串的组合。整个组合是唯一的,字符串用逗号分隔(因此是一个迷你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] 或

我需要一个数据结构,其中键基本上是两个字符串的组合。整个组合是唯一的,字符串用逗号分隔(因此是一个迷你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]

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

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

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

我建议您将密钥设置为元组:

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

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

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]]

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

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]]
编辑:这个答案与的想法有点相同,但不是像Pythonic一样,我保留这个答案,因为我有一些其他可能对你有用的东西

如果不能修改
成对的dict
结构,可以对其中的键进行预处理,以创建另外两个dict,将两个部分键映射到整体键

类似的内容应该可以让您开始假设
成对的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
('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) =>
回溯(最近一次呼叫最后一次):
文件“main.py”,第32行,在
打印(f“\t{paired\u dict\u search(search\u term)}”)
成对目录搜索中的文件“main.py”,第26行
raise VALUERROR(f“提供的索引无效:{index}”)
ValueError:提供的索引无效:3
编辑:这个答案与的想法有点相同,但不是像Pythonic一样,我保留这个答案,因为我有一些其他可能对你有用的东西

如果不能修改
成对的dict
结构,可以对其中的键进行预处理,以创建另外两个dict,将两个部分键映射到整体键

类似的内容应该可以让您开始假设
成对的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
('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) =>
回溯(最近一次呼叫最后一次):
文件“main.py”,第32行,在
打印(f“\t{paired\u dict\u search(search\u term)}”)
成对目录搜索中的文件“main.py”,第26行
raise VALUERROR(f“提供的索引无效:{index}”)
ValueError:提供的索引无效:3

到目前为止,您尝试了哪些内容?尝试中出现了哪些错误?各个部分的格式是否不同?例如,是否可能有一个像
abc,xyz这样的键?到目前为止您尝试了什么,尝试中出现了什么问题?各个部分的格式是否不同?例如,是否可以使用类似于
abc,xyz
的键?