如何有效地在 defaultdict 中进行反向查找?
how to efficiently do a reverse look up in defaultdict?
我在发布这个问题之前做了一些搜索,似乎有几种不同的方法可以完成这个。
但是目前最有效的方法是什么(使用 Python 3)根据 defaultdict
中的特定值搜索键,看起来像这样:
defaultdict(list,
{'a': [[2, 3], [1, 2]],
'b': [[5, 6]],
'w': [[]],
'x': [[9]],
'z': [[5, 6]]})
我想找到所有值为 6 的键。一种解决方案是编写一个嵌套的 for 循环来迭代键,defaultdict
的值,但我确信有一个更好的方法来完成这个。
您可以使用 itertools
模块中的 chain.from_iterable
,就像这个例子:
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']
如果您正在进行多次查找(并且 您计划进行多次查找),实际创建反向默认值可能会很有用:
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)
,但将其转换为另一个字典只需 O(n + k)
。至少如果假设 set.add
操作是 O(1)
,情况应该是这样(除了一些 - 非常罕见 - 病理情况)。
我在发布这个问题之前做了一些搜索,似乎有几种不同的方法可以完成这个。
但是目前最有效的方法是什么(使用 Python 3)根据 defaultdict
中的特定值搜索键,看起来像这样:
defaultdict(list,
{'a': [[2, 3], [1, 2]],
'b': [[5, 6]],
'w': [[]],
'x': [[9]],
'z': [[5, 6]]})
我想找到所有值为 6 的键。一种解决方案是编写一个嵌套的 for 循环来迭代键,defaultdict
的值,但我确信有一个更好的方法来完成这个。
您可以使用 itertools
模块中的 chain.from_iterable
,就像这个例子:
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']
如果您正在进行多次查找(并且
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)
,但将其转换为另一个字典只需 O(n + k)
。至少如果假设 set.add
操作是 O(1)
,情况应该是这样(除了一些 - 非常罕见 - 病理情况)。