我需要一个数据结构,其中的键本质上是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]
请注意,第一个参数是密钥对,第二个参数是该对密钥对。这样做唯一的方法是在整个字典中循环运行,直到找到所有模式为止。
答案 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