web-dev-qa-db-fra.com

Python: comment vérifier si des clés existent et récupérer la valeur du dictionnaire en ordre décroissant de priorité

J'ai un dictionnaire et je voudrais en obtenir des valeurs basées sur certaines clés. Par exemple, j'ai un dictionnaire pour les utilisateurs avec leur prénom, nom, nom d'utilisateur, adresse, âge, etc. Disons que je ne veux obtenir qu'une seule valeur (nom) - soit le nom, soit le prénom ou le nom d'utilisateur, mais en ordre décroissant comme indiqué ci-dessous:

(1) nom de famille: si la clé existe, obtenez la valeur et arrêtez la vérification. Sinon, passez à la touche suivante.

(2) prénom: si la clé existe, obtenez la valeur et arrêtez la vérification. Sinon, passez à la touche suivante.

(3) nom d'utilisateur: si la clé existe, obtenir la valeur ou retourner null/vide

#my dict looks something like this
myDict = {'age': ['value'], 'address': ['value1, value2'],
          'firstName': ['value'], 'lastName': ['']}

#List of keys I want to check in descending priority: lastName > firstName > userName
keySet = ['lastName', 'firstName', 'userName']

Ce que j'ai essayé de faire, c'est d'obtenir toutes les valeurs possibles et de les mettre dans une liste afin que je puisse récupérer le premier élément de la liste. De toute évidence, cela n'a pas fonctionné.

tempList = []

for key in keys:
    get_value = myDict.get(key)
    tempList .append(get_value)

Existe-t-il une meilleure façon de le faire sans utiliser le bloc if else?

21
Cryssie

Une option si le nombre de clés est petit est d'utiliser des chaînes enchaînées:

value = myDict.get('lastName', myDict.get('firstName', myDict.get('userName')))

Mais si vous avez défini keySet, cela pourrait être plus clair:

value = None
for key in keySet:
    if key in myDict:
        value = myDict[key]
        break

Les get enchaînés ne court-circuitent pas, donc toutes les clés seront vérifiées mais une seule utilisée. Si vous avez suffisamment de clés possibles qui comptent, utilisez la boucle for.

28
Peter DeGlopper

Utilisez .get() qui, si la clé n'est pas trouvée, renvoie None.

for i in keySet:
    temp = myDict.get(i)
    if temp is not None:
        print temp
        break
13
TerryA

Vous pouvez également utiliser myDict.has_key(keyname) pour valider si la clé existe.

Modifier en fonction des commentaires -

Cela ne fonctionnerait que sur les versions inférieures à 3.1. has_key a été supprimé de Python 3.1. Vous devez utiliser l'opérateur in si vous utilisez Python 3.1

2
Nikhil Gupta

Si nous encapsulons que dans une fonction, nous pourrions utiliser la récursivité et indiquer clairement le but en nommant la fonction correctement (je ne sais pas si getAny est en fait un bon nom):

def getAny(dic, keys, default=None):
    return (keys or default) and dic.get(keys[0], 
                                         getAny( dic, keys[1:], default=default))

ou encore mieux, sans récursivité et plus clair:

def getAny(dic, keys, default=None):
    for k in keys: 
        if k in dic:
           return dic[k]
    return default

Ensuite, cela pourrait être utilisé d'une manière similaire à la méthode dict.get, comme:

getAny(myDict, keySet)

et même avoir un résultat par défaut en cas d'absence de clés:

getAny(myDict, keySet, "not found")
1
olivecoder