简体   繁体   English

如何从列表字典的值中获取所有键?

[英]How to get all keys from a value for a dict of lists?

I have a dictionary in a format like this我有一本这样格式的字典

d = {
    "Fruit_1" : ["mango", "apple"],
    "Fruit_2" : ["apple"],
    "Fruit_3" : ["mango", "banana", "apple", "kiwi", "orange"]
}

I'm passing a value as "mango" and I want to get all corresponding keys where only mango occurs.我将一个值作为“芒果”传递,并且我想获取所有只出现芒果的对应键。 I am not able to get corresponding keys where ever value occurs.我无法在值发生的地方获得相应的键。

Iterate in d.items and check mango existence in value.迭代d.items并检查mango是否存在值。

In [21]: [key for key,value in d.items() if 'mango' in value]
Out[21]: ['Fruit_1', 'Fruit_3']

You can do this perhaps:你也许可以这样做:

d = {
    "Fruit_1" : ["mango", "apple"],
    "Fruit_2" : ["apple"],
    "Fruit_3" : ["mango", "banana", "apple", "kiwi", "orange"]
}

# list comprehension
mango_keys = [fruit for fruit in d.keys() if "mango" in d[fruit]]
print(mango_keys)       


# ['Fruit_1', 'Fruit_3']         


# or more traditional for-loop (but non pythonic)

for fruit in d.keys():
    if "mango" in d[fruit]:
        print(fruit)

The naive approaches (looping through all items and looking for the fruit) work but have a high complexity, mostly if you have to perform a lot of requests.幼稚的方法(遍历所有项目并寻找结果)有效但具有很高的复杂性,主要是在您必须执行大量请求时。 You could slightly improve it by replacing your list values by a set (for faster in lookup), but that would still be slow ( O(n**2) => O(n) but room for improvement).您可以通过用一set替换list值来稍微改进它(为了更快in查找),但这仍然会很慢( O(n**2) => O(n)但仍有改进的空间)。

If you want to be able to perform those queries a lot of times, it would be better to rebuild the dictionary so lookup is very fast once built, using collections.defaultdict如果您希望能够多次执行这些查询,最好重建字典,以便使用collections.defaultdict构建后查找非常快

d = {
    "Fruit_1" : ["mango", "apple"],
    "Fruit_2" : ["apple"],
    "Fruit_3" : ["mango", "banana", "apple", "kiwi", "orange"]
}

import collections

newd = collections.defaultdict(list)

for k,vl in d.items():
    for v in vl:
        newd[v].append(k)

print(newd)
print(newd["mango"])

this is the rebuilt dict:这是重建的字典:

defaultdict(<class 'list'>, {'apple': ['Fruit_2', 'Fruit_3', 'Fruit_1'], 'orange': ['Fruit_3'], 'banana': ['Fruit_3'], 'kiwi': ['Fruit_3'], 'mango': ['Fruit_3', 'Fruit_1']})

this is the query for "mango":这是对“芒果”的查询:

['Fruit_3', 'Fruit_1']

Like this?像这样?

>>> d = {
...     "Fruit_1" : ["mango", "apple"],
...     "Fruit_2" : ["apple"],
...     "Fruit_3" : ["mango", "banana", "apple", "kiwi", "orange"]
... }
>>> 
>>> [key for key, value in d.items() if 'mango' in value]
['Fruit_1', 'Fruit_3']

The idea is to iterate over the (key, value) itempairs and check each value for the existence of 'mango' .这个想法是迭代 (key, value) 项对并检查每个值是否存在'mango' If yes, keep the key.如果是,请保留密钥。

Since you are new to Python here's the tradidtional for -loop logic:由于您不熟悉 Python,这里是传统的for循环逻辑:

>>> result = []
>>> for key, value in d.items():
...     if 'mango' in value:
...         result.append(key)
... 
>>> result
['Fruit_1', 'Fruit_3']

For a single query, you can use a list comprehension.对于单个查询,您可以使用列表理解。 This will has O( n ) time complexity each time you search a value:每次搜索值时,这将具有 O( n ) 时间复杂度:

res = [k for k, v in d.items() if 'mango' in v]

For multiple queries, you can use a defaultdict of set objects via a one-off O( n ) cost:对于多个查询,您可以通过一次性 O( n ) 成本使用set对象的defaultdict

from collections import defaultdict

dd = defaultdict(set)

for k, v in d.items():
    for fruit in v:
        dd[fruit].add(k)

print(dd)

defaultdict({'mango': {'Fruit_1', 'Fruit_3'},
             'apple': {'Fruit_1', 'Fruit_2', 'Fruit_3'},
             'banana': {'Fruit_3'},
             'kiwi': {'Fruit_3'},
             'orange': {'Fruit_3'}})

You can then use dd['mango'] to extract relevant keys.然后您可以使用dd['mango']提取相关键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM