在 Python 字典中按值查找键的有效方法,其中字典值是可迭代的

Efficient way to find key by value in Python dict where dict values are iterables

我有一个可迭代的唯一数字:

lst = [14, 11, 8, 55]

其中每个值都在 dict 的可迭代值中的某个位置,比如列表:

dict_itms.items() = dict_items([(1, [0, 1, 2, 3]), (2, [11, 14, 12]), (3, [30, 8, 42]), (4, [55, 6])])

我必须在 dict 中找到每个 lst 元素,这样,最后,我将得到一个针对 lst 中每个元素的成对键列表。

这个方法:

keys_ = []
for a in lst:
    for k, v in dict_itms.items():
        if a in v:
            keys_ += [k]
            break
        else:
            continue

给出: [2, 2, 3, 4]

是否有更有效的方法来找到每对要查找的每个数字的每个键?

您可以在列表理解中使用 any

print([k for k,v in dict_itms.items() if any(x in lst for x in v)])

输出:

[2, 3, 4]
更新

据此 answer not set(v).isdisjoint(lst) 是最快的:

print([k for k,v in dict_itms.items() if not set(v).isdisjoint(lst)])

一个简单的 Pythonic 实现:

d = dict([(1, [0, 1, 2, 3]), (2, [11, 14, 12]), (3, [30, 8, 42]), (4, [55, 6])])

xs = [14, 11, 8, 55]

keys = [k for k, v in d.items() if set(v).intersection(xs)]
print(keys)

但是,这不会复制 2 键,而您的示例确实如此 - 不确定这是否是您需要的行为?

不清楚你所说的 'efficient' 是什么意思;你需要它在 given pass 或 aggregate 中有效吗?我问的原因是,通常最好的总体处理方式是通过预处理来翻转键值关系:

reverse_lookup = dict()
for k,v in d.items():
  for i in v:
    keys = reverse_lookup.get(i, [])  # Provide an empty list if this item not yet found
    keys.append(k)
    reverse_lookup[i] = keys

现在您已经处理了反向查找,您可以直接使用它:

result = [reverse_lookup.get(i) for i in lst]
# `result` is actually a list of lists, so as to allow duplicates. You will need to flatten it, or change the reverse lookup to ignore dupes.

反向查找的初始处理是O(n*m),其中n*m是原始字典值求和的总长度。但是,lst 部分的每次查找都是 O(1),所以如果你眯着眼睛进行足够的查找,这是 O(p),其中 plst 的长度.如果你必须做很多,这将比其他方法更有效,如果你只传递一次给定的字典,效率会低得多。