[英]I need a dict-like structure with two keys, where you can get the list of all objects with a certain value of one of them
假设我有一个看起来像这样的字典:
d['a']['1'] = 'foo'
d['a']['2'] = 'bar'
d['b']['1'] = 'baz'
d['b']['2'] = 'boo'
如果我想得到第一个键是'a'的每一个项目,我可以做d['a']
我会得到所有的。 但是,如果我想获取第二个键为“1”的所有项目怎么办? 我能想到的唯一方法是制作第二个字典,键的顺序相反,这需要复制内容。 有没有办法在一个单一的结构中做到这一点?
编辑:忘了提:我想在不迭代所有内容的情况下做到这一点。 我将要处理具有数十万个键的字典,所以我需要一些可扩展的东西。
在此示例中,您正在处理三个字典:一个具有值“foo”和“bar”,一个具有值“baz”和“boo”,以及一个映射键“a”和“b”的外部字典到前两个内部词典。 您可以使用嵌套的 for 循环遍历外部和内部字典的键:
items = []
for outer_key in d:
for inner_key in d[outer_key]:
if inner_key == "1":
items.append(d[outer_key][inner_key])
break # No need to keep checking keys once you've found a match
如果您不关心外部字典的键,您也可以使用d.values()
忽略键并只查看内部字典,然后对这些进行直接成员资格检查:
items = []
for inner_dict in d.values():
if "1" in inner_dict:
items.append(inner_dict["1"])
这也可以写成列表推导:
items = [inner_dict["1"] for inner_dict in d.values() if "1" in inner_dict]
你想要的听起来非常类似于可以作为字典字典实现的树结构。 这是一个简单的实现,取自问题的答案之一实现嵌套字典的最佳方法是什么? :
class Tree(dict):
def __missing__(self, key):
value = self[key] = type(self)()
return value
def get_second_level(self, second_key):
found = []
for level2 in self.values():
if second_key in level2:
found.append(level2[second_key])
return found
d = Tree()
d['a']['1'] = 'foo'
d['a']['2'] = 'bar'
d['b']['1'] = 'baz'
d['b']['2'] = 'boo'
d['c']['2'] = 'mox'
d['c']['3'] = 'nix'
print(d) # -> {'a': {'1': 'foo', '2': 'bar'}, 'b': {'1': 'baz', '2': 'boo'},
# 'c': {'2': 'mox', '3': 'nix'}}
print(d['a']) # -> {'1': 'foo', '2': 'bar'}
print(d['a']['1']) # -> foo
print(d['a']['2']) # -> bar
print()
second_key = '1'
found = d.get_second_level(second_key)
print(f'Those with a second key of {second_key!r}') # -> Those with a second key of '1'
print(f' {found}') # -> ['foo', 'baz']
因此,在睡了之后,我想出的解决方案是制作三个字典,其中数据实际存储并由元组( d['a', '1'] = 'foo'
)标识的主要字典和另一个两个是在键 A 下存储键 B 的所有可能值的索引,其中 (A,B) 是有效组合(因此a['a'] = ['1', '2']
, b['1'] = ['a', 'b']
. 我不完全喜欢这个,因为它仍然需要大量的存储开销并且不能有效地扩展到更多的键,但是它可以在不迭代和不复制的情况下完成工作数据。如果有人有更好的主意,我会很高兴听到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.