How to find the name of the key in a dictionary by the value contained in it?

Asked

Viewed 2,266 times

2

Here is an example.

dicio = {'pizza': {'massa', 'ketchup'}, 'feijoada': {'feijão', 'linguiça'}}

user_input = 'feijão', 'linguiça' #Input

How to check if this input is in the values of this list and if it is as I can from this take the name of the key that has these values and printar pro user ?

2 answers

3


Usually, what you’re doing is the opposite of a traditional mapping.

Now, you can turn your multimapa into another multimapa, this time with reversed keys/values. Here I describe a little better a multimap, so I won’t go back too far to the formalisms of this definition.

reverse_multimapa = {}
for chave_original, valores in dicio.items():
    for valor in valores:
        try:
            # se chave existir, tudo funciona corretamente
            reverse_multimapa[valor].append(chave_original)
        except KeyError:
            # se chave não existir, vai cair aqui
            reverse_multimapa[valor] = [chave_original]

So the reverse search would just pass the desired value to the reverse_multimapa and get their values. Note that in this case I am predicting that the case in which 'pizza' and 'sanduíche' have as one of the associated values 'ketchup'.

In this case:

print(reverse_multimapa['ketchup'])

Would return:

['pizza', 'sanduíche']

An alternative using pure Python dictionaries is to use the method setdefault at the rescue. This avoids treating the exception (or treating the None, if the method is used get). Tip courtesy of @jsbueno in your comment.

reverse_multimapa = {}
for chave_original, valores in dicio.items():
    for valor in valores:
        reverse_multimapa.setdefault(valor, []).append(chave_original)

As indicated by @Andersoncarloswoss in your comment, what I did there with the try-except has already been done in Python very efficient and idiomatic way. Could have used the collections.defaultdict.

Coincidentally, the example provided by the documentation itself is to create multi-maps.

Taking this opportunity, I would like to warn you about the use of this strategy here against the previous strategy, documented in the example of the use of collections.defaultdict, which deals specifically with creating a list if the element does not exist in the dictionary and, if it exists, add to it:

This technique is Simpler and Faster than an equivalent technique using Dict.setdefault()

In free translation:

This technique is simpler and faster than the equivalent technique using Dict.setdefault()

Using the collections.defaultdict, would thus be the construction of reverse_multimapa:

reverse_multimapa = collections.defaultdict(list)
for chave_original, valores in dicio.items():
    for valor in valores:
        reverse_multimapa[valor].append(chave_original)

The use of reverse_multimapa remains identical, only its creation is easier and readable.

  • 1

    An alternative to the block try/except is to use the collections.defaultdict.

  • @Andersoncarloswoss much simpler, I didn’t know that.

  • 1

    Nowadays it’s hard for me to use the defaultdict dicionários padrão tem o método setdefaultque daz a mesma coisa:reverse_multimapa.setdefault(value, []). append(original key_key)`

  • 1

    @jsbueno that gives you know the least possible language to write algorithms. Thanks for the tip, it seems even more elegant than the defaultdict. My feeling is that in Python it really is all with import antigravity, just remember what you want

  • 1

    what I am cool about Python is just this - with the minimum of the fdá language to write any algorithm. The facilities and best practices, get over time and doing - and interact around here is to be "doing".

  • 1

    Now that you’re there, take a look at "extradict' - it’s a kind of toy module, kind of serious, where I put in some experimental dictionaries. One of them is a dictionary that makes the return "value, key" automatic (extradict.BijectiveDict)

  • It’s easy to find on Google, but I’ll leave the link here: https://github.com/jsbueno/extradict

  • @jsbueno I think it would be an interesting response to with the BijectiveDict ;-) Since she apparently does not follow the idea of the multimope strictly, I do not go for it in my reply

  • 1

    Yeah, the problem here is a little different. Bijectivedict even has multimedia support, but when you start backwards: multiple keys for a single value. But in this case, what the user might want to do with the map is complicated - the simplest is to allow only one-to-one relationships. Keys pointing to the same value unmount the previous relation.

Show 4 more comments

0

A very basic example:

dicio = {'pizza': {'massa', 'ketchup'}, 'feijoada': {'feijão', 'linguiça'}}

def search(term):
    for k, v in dicio.items():
        if term in v:
            return k

    return None

print(search('massa'))
print(search('linguiça'))

You just need to adapt the code to take user input and perform the search.

  • I recommend using Python 3 by default to answer Python questions. Python 2 is already less used, and for beginners it makes less sense to give python 2 tips, since they should really be learning the newer version.

  • Roger @jsbueno!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.