Get the key which has multiple value by its values in a dictionary

Viewed 341

I have a dictionary which its keys has multiple values, I have a list which some of its items are values from the dictionary and some are not. what I'm trying to do is to read every item in that list and if it was a value in the dictionary, append the key pair of it to another list and if it wasn't append the item itself, but I keep get nothing

d = {'salam':('hi', 'ciao', 'bonjour'), 'mamnoon':('thanks', 'grazie', 'merci')}
l = ['hi', 'thanks', 'very', 'much']
l1 = []
for i in range(0, len(l)):
    search_val = l[i]
    for key, val in d.items():
        if val == search_val:
            l1.append(key)
        else:
            l1.append(l[i])
print(l1)

the output that I'm looking for is this but I keep receiving an empty list

['salam', 'mamnoon', 'very', 'much']
3 Answers

You're looking for if search_val in val instead of if val == search_val, since val is a tuple of multiple strings and you don't want to test whether your search_val is equal to the full tuple, just whether the tuple contains your search_val.

Since your expected output includes those strings which could not be found in the values of your dictionary, you could write something like:

d = {'salam':('hi', 'ciao', 'bonjour'), 'mamnoon':('thanks', 'grazie', 'merci')}
l = ['hi', 'thanks', 'very', 'much']
l1 = []
for search_val in l:
    for key, val in d.items():
        if search_val in val:
            l1.append(key)
            break
    else:
        l1.append(search_val)
print(l1)

Output:

['salam', 'mamnoon', 'very', 'much']

Here, we stop searching the dictionary once we found the key with the search_val (since we assume that only one key will have this value in its tuple). The else clause of the for loop will be executed if the loop completes normally (i.e. does not exit because of hitting the break statement), which corresponds to the search_val not being found. In this case, we append the search_val to l1.

An alternative without using the for/else syntax could use a found flag:

d = {'salam':('hi', 'ciao', 'bonjour'), 'mamnoon':('thanks', 'grazie', 'merci')}
l = ['hi', 'thanks', 'very', 'much']
l1 = []
for search_val in l:
    found = False
    for key, val in d.items():
        if search_val in val:
            l1.append(key)
            found = True
    if not found:
        l1.append(search_val)
print(l1)

your solution is almost true but you need to edit the condition in the inner for loop

val : is a tuple and the result of comparing a tuple and string will be false so it appends nothing and you will get an empty list.

instead of if val == search_val: try if search_val in val:

this will result in l1 = ['salam', 'mamnoon']

What about a combination of itertools.chain() method in combination of some list comprehension to do this in one line:

import itertools 
d = {'salam':('hi', 'ciao', 'bonjour'), 'mamnoon':('thanks', 'grazie', 'merci')}
l = ['hi', 'thanks', 'very', 'much']
l1 = [i if not i in itertools.chain(*d.values()) else [key for key in d if i in d[key]][0] for i in l]
print(l1)

Returns:

['salam', 'mamnoon', 'very', 'much']
Related