2010-06-21 16 views
35

Was ist die prägnanteste Art zu sagen, in Python, "Gib mir dict['foo'], wenn es existiert, und wenn nicht, geben Sie mir diesen anderen Wert bar"? Wenn ich ein Objekt bin mit eher als ein Wörterbuch, würde ich getattr verwenden:Python getattr Äquivalent für Wörterbücher?

getattr(obj, 'foo', bar) 

aber dies wirft einen Schlüssel Fehler, wenn ich stattdessen ein Wörterbuch versuchen, mit (a Unterscheidung, die ich schade finde kommen von JavaScript/Coffeescript). Ebenso würde ich in JavaScript/CoffeeScript einfach

dict['foo'] || bar 

schreiben, aber dies wiederum ergibt einen KeyError. Was ist zu tun? Etwas prägnant, bitte!

Antwort

58

dict.get(key, default) gibt dict[key] zurück, wenn dict eingibt, sonst gibt Standard zurück.

Beachten Sie, dass die Standardeinstellung für default ist None also, wenn Sie dict.get(key) sagen und Schlüssel ist in dict nicht, dann wird dies None nur zurück, anstatt eine KeyError Anhebung wie passiert, wenn Sie die [] Notation Schlüsselzugriff verwenden.

+0

Danke, das ist genau das, was ich gesucht habe! Ich denke du hast gerade einen neuen Geschwindigkeitsrekord aufgestellt. –

+0

Hey ist es möglich, dies nur für eine bestimmte Eigenschaft des Schlüssels zu tun ... [Hier] (http://stackoverflow.com/a/6467555/5961780), ein Wert wird nur zurückgegeben, wenn "Schlüssel", oder besser gesagt " Name ', beginnt mit dem Buchstaben' f '. – sbrm1

5

Werfen Sie auch einen Blick auf die Defaultdict-Klasse des Collections-Moduls. Es ist ein Diktat, für das Sie angeben können, was zurückgegeben werden soll, wenn der Schlüssel nicht gefunden wird. Mit ihm können Sie Dinge tun wie:

class MyDefaultObj: 
    def __init__(self): 
     self.a = 1 

from collections import defaultdict 
d = defaultdict(MyDefaultObj) 
i = d['NonExistentKey'] 
type(i) 
<instance of class MyDefalutObj> 

was ermöglicht Ihnen, die vertraute d [i] Konvention zu verwenden.

Doch wie MikeJ sagte .get() funktioniert auch, aber hier ist die Form näher an Ihrem JavaScript-Beispiel:

d = {} 
i = d.get('NonExistentKey') or MyDefaultObj() 
# the reason this is slightly better than d.get('NonExistent', MyDefaultObj()) 
# is that instantiation of default value happens only when 'NonExistent' does not exist. 
# With d.get('NonExistent', MyDefaultObj()) you spin up a default every time you .get() 
type(i) 
<instance of class MyDefalutObj>