Dave Opstad wrote:
In this snippet:

d = {'x': 1}
value = d.get('x', bigscaryfunction())

the bigscaryfunction is always called, even though 'x' is a valid key. Is there a "short-circuit" version of get that doesn't evaluate the second argument if the first is a valid key? For now I'll code around it, but this behavior surprised me a bit...

Dave
If (and this is a big if) you know that the dictionary contains no values that evaluate to boolean false, then you can use the short-circuiting 'or' operator:

 >>> def bigscaryfunction():
 ...     print "scary"
 ...
 >>> d= globals()
 >>> d.get("key") or bigscaryfunction()
 scary
 >>> d.get("__name__") or bigscaryfunction()
 'LazyDictget'
 >>>

Alternatively, you can just write your own getter function:
 >>> def lazyget(dict_, key, default):
 ...     if key in dict_:
 ...         return dict_[key]
 ...     else:
 ...         return default()
 ...
 >>> lazyget(d,"key",bigscaryfunction)
 scary
 >>> lazyget(d,"__name__",bigscaryfunction)
 'LazyDictget'
 >>>

The optimal choice of whether to "look before you leap" i.e., "if key in dict_" or simply catch KeyError, depends on the ratio of hits to misses. Google will turn up some experimental data on this, but, I seem to recall that if more than 10% attempts are misses, then LBYL is faster, because raising the exception is slow


Michael


-- http://mail.python.org/mailman/listinfo/python-list

Reply via email to