0

I want to check if two items are in a list. But the method should follow a kind of order.

Here, I have a dictionary of people along with their favorite numbers. But the numbers are the keys and the people are the values.

fav_num_dict = {13: 'A', 33: 'B', 23: 'C', 25: 'D', 11: 'E', 4: 'F'}

people_to_check = ["D", "B"]

for num, person in fav_num_dict.items():
    if person in people_to_check:
        print(fav_num_dict[num], num)

I am doing some kind of work where the order of the people in people_to_check matters. But when I run the script, it prints "B", with his/her number first and then "D". Now, that happens because "B" comes first in the dictionary and it also exists in people_to_check despite as the second item.

My question here is how do I make the program respect my order for people_to_check? Like, if it finds "B" first but it is the second item in my specified list, it should wait until it finds the first item, "D" and then "B".

I can also do a people_to_check.reverse() but that always won't work. Because people_to_check can also have items that are in order with the items in fav_num_dict

Arafat Khan
  • 777
  • 1
  • 10
  • 24
  • 2
    Your dictionary structure is error prone. Two people can have same favourite number. Invert your dictionary. – Austin Aug 29 '19 at 14:24
  • 2
    What if you iterate over the list people_to_check rather than fav_num_dict to maintain the correct order? – yabhishek Aug 29 '19 at 14:25
  • 2
    Just a point that there is no guarantee that a dictionary should maintain order. You should be looping over the search terms if you want results in that order, not over the items in the dictionary. – Mr Felix U Aug 29 '19 at 14:30
  • @MrFelixU Python 3.7 preserves dict insertion order. So does CPython 3.6, but it's an implementation detail. See [Are dictionaries ordered in Python 3.6+?](https://stackoverflow.com/q/39980323/4518341) But anyway it's beside the point cause like you said OP should be looping over the list, not the dict. – wjandrea Aug 29 '19 at 14:43
  • @wjandrea Indeed, but as you say that's not a language feature, it just so happens to be the case in the current implementation and I thought it was unwise to rely on that in one's algorithm. – Mr Felix U Aug 29 '19 at 14:47
  • @MrFelixU Your point stands, but it is a language feature in Python 3.7+. It's an implementation detail in CPython 3.6. – wjandrea Aug 29 '19 at 14:51

4 Answers4

2

you can invert your dictionary (if the names are unique...) then just use a regular dict lookup:

fav_num_dict = {13: 'A', 33: 'B', 23: 'C', 25: 'D', 11: 'E', 4: 'F'}

reverse_dict = {v: k for k, v in fav_num_dict.items()}

people_to_check = ["D", "B"]

for person in people_to_check:
    if person in reverse_dict:
        print(person, reverse_dict[person])

Output:

D 25
B 33
Adam.Er8
  • 12,675
  • 3
  • 26
  • 38
  • I appreciate your opinion to invert the dictionary but there can be scenarios where my structure might be preferred. An example is a dictionary where the keys are "Person 1", "Person 2", etc.. and the values are their names? And I have to check if a person exists in that dict? I need to iterate over dict.items() since I need both the key and value. Thanks to the above comments, I iterated over my list and then I iterated over dict.items() and then checked if the person is the value of any item in the dict. My apologies for not using an idea dictionary as an example. – Arafat Khan Aug 29 '19 at 15:30
0

You will get the desired order by iterating over the list people_to_check and querying the reversed_dictionary if the person is present in it. For example, you can do something like-

fav_num_dict = {13: 'A', 33: 'B', 23: 'C', 25: 'D', 11: 'E', 4: 'F'}
reversed_dict = dict((val,key) for key, val in fav_num_dict.items())

people_to_check = ["D", "B"]

for person in people_to_check:
    if person in reversed_dict:
        print(person, reversed_dict[person])

This will work only if each number is uniquely associated to a person, if a person who likes more than two numbers and is one of the people_to_check, you might get one of the numbers that he likes and not all.

yabhishek
  • 408
  • 4
  • 14
  • `dict()` can take a generator, so the list is not needed: `dict((val, key) for key, val in fav_num_dict.items())`. It's even simpler to do a dict comprehension like in Adam's answer: `{v: k for k, v in fav_num_dict.items()}` – wjandrea Aug 29 '19 at 14:40
  • 1
    @ wjandrea: Thanks for the the suggestion. Modified the answer. – yabhishek Aug 29 '19 at 14:49
0

There is also another way that you iterate on people_to_check and then find the key associated with the value present in people_to_check by using dict.keys() and dict.values().

fav_num_dict = {13: 'A', 33: 'B', 23: 'C', 25: 'D', 11: 'E', 4: 'F'}
people_to_check = ["D", "B", "E"]
for person in people_to_check:
    if person in fav_num_dict.values():
        k = 0
        while fav_num_dict[list(fav_num_dict.keys())[k]] != person:
            k = k+1
        print(person, list(fav_num_dict.keys())[k])

Hope this is helpful

Ashu007
  • 745
  • 1
  • 9
  • 13
0

Alternatively you can also make a function and you'll get key of any value inside a dict by using function by passing dict and a value for which you have to find key to it. go through this link Get key by value in dictionary

Ashu007
  • 745
  • 1
  • 9
  • 13