我在发布这个问题之前做了一些搜索,似乎有几种不同的方法来实现这一点。
但是目前(使用Python 3)根据defaultdict
中的特定值搜索关键字的最有效方法是什么,它看起来像这样:
defaultdict(list,
{'a': [[2, 3], [1, 2]],
'b': [[5, 6]],
'w': [[]],
'x': [[9]],
'z': [[5, 6]]})
我想找到值为6的所有键。一种解决方案是编写一个嵌套的for循环,迭代defaultdict
的键值,但我相信有更好的方法要做到这一点。
答案 0 :(得分:1)
您可以使用chain.from_iterable
模块中的itertools
,例如:
from itertools import chain
a = defaultdict(list,
{'a': [[2, 3], [1, 2]],
'b': [[5, 6]],
'w': [[]],
'x': [[9]],
'z': [[5, 6]]})
keys = [k for k, v in a.items() if 6 in chain.from_iterable(v)]
print(keys)
或者,以更紧凑的方式,您可以定义一个在defaultdict值中进行查找的函数:
def get_keys(a, key=6):
return [k for k, v in a.items() if key in chain.from_iterable(v)]
keys = get_keys(a)
print(keys)
输出:
['b', 'z']
答案 1 :(得分:1)
如果您正在进行多次查找(以及in the comments you said,您计划进行多次查找),实际创建反向违约可能会有用:
from collections import defaultdict
inp = defaultdict(list, {'a': [[2, 3], [1, 2]], 'b': [[5, 6]], 'w': [[]], 'x': [[9]], 'z': [[5, 6]]})
res = defaultdict(set)
for key, vallist in inp.items():
for valsublist in vallist:
for val in valsublist:
res[val].add(key)
然后只需访问res
即可进行查找。
例如:
>>> res[6]
{'z', 'b'}
>>> res[2]
{'a'}
您将始终需要遍历所有defaultdicts值中的所有项目(这需要O(n)
,其中n
是所有值列表中所有项目的数量)。但是(在大多数情况下)查找字典中的密钥O(1)
。因此,如果您计划进行多次查询,请说k
,那么多次执行迭代需要O(n*k)
,但将其转换为另一个dict只会O(n + k)
。至少如果假设set.add
操作是O(1)
,那应该是这种情况(除了一些 - 非常罕见的 - 病态情况)。