Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Is there a short-circuiting dictionary "get" method?

Reply
Thread Tools

Is there a short-circuiting dictionary "get" method?

 
 
Dave Opstad
Guest
Posts: n/a
 
      03-09-2005
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
 
Reply With Quote
 
 
 
 
Peter Hansen
Guest
Posts: n/a
 
      03-09-2005
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...


try:
value = d['x']
except KeyError:
value = bigscaryfunction()

get() is just a method, and arguments to methods are always
evaluated before being passed to the method, so the short
answer is "no, there is no 'version' of get() that will do
what you want".

-Peter
 
Reply With Quote
 
 
 
 
Bill Mill
Guest
Posts: n/a
 
      03-09-2005
Dave,

On Wed, 09 Mar 2005 09:45:41 -0800, Dave Opstad <(E-Mail Removed)> 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...


There is no short-circuit function like you're asking for, because
it's impossible in python. To pass an argument to the 'get' function,
python evaluates the bigscaryfunction before calling 'get'.

(I believe this means that python doesn't have "lazy evaluation", but
the language lawyers may shoot me down on that. Wikipedia seems to say
that it means python doesn't have "delayed evaluation").

Here are two ways to do what you want:

if 'x' in d: value = d['x']
else: value = bigscaryfunction()

or:

def sget(dict, key, func, *args):
if key in dict: return key
else: return func(*args)

sget(d, 'x', bigscaryfunction)

Both methods are untested, but should work with minor modifications.

Peace
Bill Mill
bill.mill at gmail.com
 
Reply With Quote
 
bearophileHUGS@lycos.com
Guest
Posts: n/a
 
      03-09-2005
Maybe this can help:

value = d.get('x', lambda: bigscaryfunction())

Bearophile

 
Reply With Quote
 
F. Petitjean
Guest
Posts: n/a
 
      03-09-2005
Le Wed, 09 Mar 2005 09:45:41 -0800, Dave Opstad a écrit :
> 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...

def scary():
print "scary called"
return 22

d = dict(x=1)
d.get('x', lambda *a : scary())
# print 1
d.get('z', (lambda *a : scary())())
scary called
22

First (wrong) version :
d.get('z', lambda *a : scary())
<function <lambda> at 0x40598e9c>
>
> Dave

 
Reply With Quote
 
Bill Mill
Guest
Posts: n/a
 
      03-09-2005
On 9 Mar 2005 10:05:21 -0800, http://www.velocityreviews.com/forums/(E-Mail Removed)
<(E-Mail Removed)> wrote:
> Maybe this can help:
>
> value = d.get('x', lambda: bigscaryfunction())


>>> def test(): print 'gbye'

....
>>> d = {}
>>> z = d.get('x', lambda: test())
>>> z

<function <lambda> at 0x008D6870>

So this seems to be merely an obfuscation of:

>>> z = d.get('x', test)
>>> z

<function test at 0x008D66B0>

I just wanted to ask, am I missing something?

Peace
Bill Mill
bill.mill at gmail.com
 
Reply With Quote
 
Bill Mill
Guest
Posts: n/a
 
      03-09-2005
On 09 Mar 2005 18:13:01 GMT, F. Petitjean <(E-Mail Removed)> wrote:
> Le Wed, 09 Mar 2005 09:45:41 -0800, Dave Opstad a écrit :
> > 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...

> def scary():
> print "scary called"
> return 22
>
> d = dict(x=1)
> d.get('x', lambda *a : scary())
>
> # print 1
> d.get('z', (lambda *a : scary())())
> scary called
> 22


but:

>>> d.get('x', (lambda *a: test())())

test called
1

So how is this different than d.get('x', test()) ?

Peace
Bill Mill
bill.mill at gmail.com
 
Reply With Quote
 
Kent Johnson
Guest
Posts: n/a
 
      03-09-2005
F. Petitjean wrote:
> Le Wed, 09 Mar 2005 09:45:41 -0800, Dave Opstad a écrit :
>>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...

>
> def scary():
> print "scary called"
> return 22
>
> d = dict(x=1)
> d.get('x', lambda *a : scary())
> # print 1
> d.get('z', (lambda *a : scary())())
> scary called
> 22


So you have to change the code at the point of call depending on whether the requested value is in
the dict?

If you can get this to work I'm sure we can find other applications for such 'smart code'

Kent
 
Reply With Quote
 
Skip Montanaro
Guest
Posts: n/a
 
      03-09-2005

Dave> In this snippet:
Dave> d = {'x': 1}
Dave> value = d.get('x', bigscaryfunction())

Dave> the bigscaryfunction is always called, even though 'x' is a valid
Dave> key.

I sometimes use

value = d.get('x') or bsf()

Of course, this bsf() will get called if d['x'] evaluates to false, not just
None, so it won't work in all situations. It may help often enough to be
useful though.

Skip
 
Reply With Quote
 
Reinhold Birkenfeld
Guest
Posts: n/a
 
      03-09-2005
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...


Well, if the dict only contains ints, here is a dirty hack (but don't
use it instead of the try/except approach):

class Littletinyproxy:
def __int__(self):
return bigscaryfunction()

d = dict(x=1)
value = int(d.get('x', Littletinyproxy()))


Reinhold
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Performance ordered dictionary vs normal dictionary Navkirat Singh Python 6 07-29-2010 10:18 AM
Re: Performance ordered dictionary vs normal dictionary Chris Rebert Python 0 07-29-2010 06:11 AM
creating a dictionary from a dictionary with regex james_027 Python 1 08-22-2007 07:39 AM
[DICTIONARY] - Copy dictionary entries to attributes Ilias Lazaridis Python 6 02-21-2006 11:27 AM
dictionary within dictionary Fox ASP General 5 03-13-2005 05:03 AM



Advertisments