3

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.

Georgy
  • 12,464
  • 7
  • 65
  • 73
Mayank Srivastava
  • 149
  • 1
  • 3
  • 18

5 Answers5

9

Iterate in d.items and check mango existence in value.

In [21]: [key for key,value in d.items() if 'mango' in value]
Out[21]: ['Fruit_1', 'Fruit_3']
Rahul K P
  • 15,740
  • 4
  • 35
  • 52
2

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)
BlackBeard
  • 10,246
  • 7
  • 52
  • 62
2

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).

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

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']
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
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'. If yes, keep the key.

Since you are new to Python here's the tradidtional for-loop logic:

>>> result = []
>>> for key, value in d.items():
...     if 'mango' in value:
...         result.append(key)
... 
>>> result
['Fruit_1', 'Fruit_3']
timgeb
  • 76,762
  • 20
  • 123
  • 145
1

For a single query, you can use a list comprehension. This will has O(n) time complexity each time you search a value:

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:

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.

jpp
  • 159,742
  • 34
  • 281
  • 339