web-dev-qa-db-fra.com

obtenir la clé par valeur, dict, python

Comment puis-je obtenir une clé d'une valeur? 

mon dict: 

countries = {
        "Normal UK project" : "1",
        "UK Omnibus project" : "1-Omni",
        "Nordic project" : ["11","12","13","14"],
        "German project" : "21",
        "French project" : "31"
        }

mon code semi-fonctionnel:

for k, v in countries.items():
    if "1" in v:
        print k

production attendue:

Normal UK project

rendement réel: 

French project
UK Omnibus project
German project
Normal UK project

Comment puis-je réparer mon code? 

8
Boosted_d16

Le problème est que les types de valeurs dans le dictionnaire ne sont pas identiques, ce qui rend l'utilisation du dictionnaire beaucoup plus difficile, pas seulement dans ce scénario. Bien que Python le permette, vous devriez vraiment envisager d’unifier les types du dictionnaire, par exemple. faites-les toutes les listes. Vous pouvez le faire en une seule ligne de code:

countries = {key: val if isinstance(val, list) else [val] 
                        for key, val in countries.items()}

Désormais, chaque chaîne est encapsulée dans une liste et votre code existant fonctionnera correctement.

Sinon, si vous devez utiliser le dictionnaire dans sa forme actuelle, vous pouvez adapter votre fonction de recherche:

for k, v in countries.items():
    if "1" == v or isinstance(v, list) and "1" in v:
        print k
7
tobias_k

c={} - n'importe quel dict
a (valeur) - vous devez connaître cette clé

key=list(c.keys())[list(c.values()).index(a)]]
6
def keys_of_value(dct, value):
    for k in dct:
        if isinstance(dct[k], list):
            if value in dct[k]:
                return k
        else:
            if value == dct[k]:
                return k

assert keys_of_value(countries, "12") == "Nordic project"
assert keys_of_value(countries, "1")  == "Normal UK project"

Si vous voulez que je le raccourcisse un peu, je pourrais le faire

from operator import eq, contains

def keys_of_value(dct, value, ops = (eq, contains)):
    for k in dct:
        if ops[isinstance(dct[k], list)](dct[k], value):
            return k

assert keys_of_value(countries, "12") == "Nordic project"
assert keys_of_value(countries, "1") == "Normal UK project"
3
thefourtheye

Le code suivant fournit une autre version abrégée de l'obtention des clés de dictionnaire par une valeur, en utilisant list comprehensions et dic.items ():

keys_have_value = [k for k,v in dic.items() if v=="1"]
3
Serjik

Votre code semi-fonctionnel renvoie les autres valeurs car avec des entrées telles que:

    "Normal UK project" : "1",

..then "1" in v vérifie si la chaîne contient le caractère "1", alors qu'avec des entrées comme:

    "Nordic project" : ["11","12","13","14"],

..then vérifiera si la liste contient un élément "1".

L'opérateur in fonctionne sur les chaînes et les listes, mais de manière différente:

>>> "1" in "123"
True
>>> "1" in ["123", "blah"]
False
>>> "1" in ["1", "blah"]
True

Idéalement, vos données seraient plus cohérentes - toutes les listes ou toutes les chaînes:

countries = {
        "Normal UK project" : ["1"],
        "UK Omnibus project" : ["1-Omni"],
        "Nordic project" : ["11","12","13","14"],
        "German project" : ["21"],
        "French project" : ["31"]
        }

for k, v in countries.items():
    if "1" in v:
        print k
2
dbr
def get_Value(dic,value):
    for name in dic:
        if dic[name] == value:
            return name
0
Raj Damani

Personnellement, je pense que l'utilisation de in et de la fonction values est plus facile. 

print 1 in {1:"123", 2:"blah"}
print "blah" in {1:"123", 2:"blah"}.values()

La sortie est: 

True
True
0
Ehsan Ab