Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Check for dict key existence, and modify it in one step.

Reply
Thread Tools

Check for dict key existence, and modify it in one step.

 
 
rodrigo
Guest
Posts: n/a
 
      08-28-2007
Im using this construct a lot:

if dict.has_key(whatever):
dict[whatever] += delta
else:
dict[whatever] = 1

sometimes even nested:

if dict.has_key(whatever):
if dict[whatever].has_key(someother):
dict[whatever][someother] += delta
else:
dict[whatever][someother] = 1
else:
dict[whatever]={}
dict[whatever][someother] = 1

there must be a more compact, readable and less redundant way to do
this, no?

Thanks,

Rodrigo

 
Reply With Quote
 
 
 
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      08-28-2007
rodrigo a écrit :
> Im using this construct a lot:
>
> if dict.has_key(whatever):


<ot>
Avoid using builtin names as identifiers (it shadows the builtin name).
</ot>

Unless you're using an old Python version, you'd be better using
if whatever in my_dict:
# do something here

> dict[whatever] += delta
> else:
> dict[whatever] = 1
>
> sometimes even nested:
>
> if dict.has_key(whatever):
> if dict[whatever].has_key(someother):
> dict[whatever][someother] += delta
> else:
> dict[whatever][someother] = 1
> else:
> dict[whatever]={}
> dict[whatever][someother] = 1
>
> there must be a more compact, readable and less redundant way to do
> this, no?


There are other ways, yes. With Python <= 2.4.x, you can use
dict.setdefault, with Python 2.5.x you can use a defaultdict (cf
http://docs.python.org/whatsnew/modules.html).

HTH
 
Reply With Quote
 
 
 
 
Jason
Guest
Posts: n/a
 
      08-28-2007
On Aug 28, 8:36 am, rodrigo <(E-Mail Removed)> wrote:
> Im using this construct a lot:
>
> if dict.has_key(whatever):
> dict[whatever] += delta
> else:
> dict[whatever] = 1
>
> sometimes even nested:
>
> if dict.has_key(whatever):
> if dict[whatever].has_key(someother):
> dict[whatever][someother] += delta
> else:
> dict[whatever][someother] = 1
> else:
> dict[whatever]={}
> dict[whatever][someother] = 1
>
> there must be a more compact, readable and less redundant way to do
> this, no?
>
> Thanks,
>
> Rodrigo


As Bruno said, don't shadow the built-in objects. When things
inevitably go south because the dict class has been replaced by your
dictionary, it will be difficult for you to find out what went wrong.

Under Python 2.5, you have the defaultdict class in the collections
module [1]. (This class is trivial to implement in prior versions of
Python, too.)

>>> from collections import defaultdict
>>> myDict = defaultdict(lambda: 1)
>>> myDict['spam'] = 5
>>> myDict['spam'] += 10
>>> myDict['vikings'] += 20
>>> myDict

defaultdict(<function <lambda> at 0x00AAC970>, {'vikings': 21, 'spam':
15})
>>>


--Jason

[1] The module documentation is at "http://docs.python.org/lib/module-
collections.html"

 
Reply With Quote
 
Evan Klitzke
Guest
Posts: n/a
 
      08-28-2007
On Tue, 2007-08-28 at 14:36 +0000, rodrigo wrote:
> Im using this construct a lot:
>
> if dict.has_key(whatever):
> dict[whatever] += delta
> else:
> dict[whatever] = 1


In Python 2.5 there's a defaultdict class, otherwise you can subclass
dict like this:

class CountingDictionary(dict):
def increment(self, key, delta=1):
self[key] = self.get(key, 0) + delta

Hope this helps!

--
Evan Klitzke <(E-Mail Removed)>

 
Reply With Quote
 
rodrigo
Guest
Posts: n/a
 
      08-28-2007
evan,

yes, it does help. Works like it should:

class CountingDictionary(dict):
def increment(self, key, delta=1):
self[key] = self.get(key, 0) + delta

d = CountingDictionary()
d.increment('cat')
d.increment('dog',72)
print d

>>> {'dog': 72, 'cat': 1}


Thanks!

 
Reply With Quote
 
rodrigo
Guest
Posts: n/a
 
      08-28-2007
You're right of course, I was unclear. I wasn't using 'dict' to
override the dict clas, but just as a standin for the example (the
actual dictionary names are varied).

Thanks,

Rodriog

 
Reply With Quote
 
Ben Finney
Guest
Posts: n/a
 
      08-28-2007
rodrigo <(E-Mail Removed)> writes:

> Im using this construct a lot:
>
> if dict.has_key(whatever):
> dict[whatever] += delta
> else:
> dict[whatever] = 1


I'd prefer:

foo.setdefault(whatever, 0)
foo[whatever] += delta

> sometimes even nested:
>
> if dict.has_key(whatever):
> if dict[whatever].has_key(someother):
> dict[whatever][someother] += delta
> else:
> dict[whatever][someother] = 1
> else:
> dict[whatever]={}
> dict[whatever][someother] = 1


foo.setdefault(whatever, {})
foo[whatever].setdefault(someother, 0)
foo[whatever] += delta

> there must be a more compact, readable and less redundant way to do
> this, no?


Hope that helps.

--
\ "I took a course in speed waiting. Now I can wait an hour in |
`\ only ten minutes." -- Steven Wright |
_o__) |
Ben Finney
 
Reply With Quote
 
Ben Finney
Guest
Posts: n/a
 
      08-28-2007
Ben Finney <(E-Mail Removed)> writes:

> foo.setdefault(whatever, {})
> foo[whatever].setdefault(someother, 0)
> foo[whatever] += delta


Should, of course, be:

foo.setdefault(whatever, {})
foo[whatever].setdefault(someother, 0)
foo[whatever][someother] += delta

--
\ "My house is made out of balsa wood, so when I want to scare |
`\ the neighborhood kids I lift it over my head and tell them to |
_o__) get out of my yard or I'll throw it at them." -- Steven Wright |
Ben Finney
 
Reply With Quote
 
Dustan
Guest
Posts: n/a
 
      08-29-2007
On Aug 28, 1:13 pm, rodrigo <(E-Mail Removed)> wrote:
> evan,
>
> yes, it does help. Works like it should:
>
> class CountingDictionary(dict):
> def increment(self, key, delta=1):
> self[key] = self.get(key, 0) + delta
>
> d = CountingDictionary()
> d.increment('cat')
> d.increment('dog',72)
> print d
>
> >>> {'dog': 72, 'cat': 1}

>
> Thanks!


You responded to the answer that made the least use of already
existing recourses in python. Just letting you know.

 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      08-29-2007
rodrigo a écrit :
> You're right of course, I was unclear. I wasn't using 'dict' to
> override the dict clas, but just as a standin for the example (the
> actual dictionary names are varied).


I guessed so, but Python's behaviour wrt/ naming can be somewhat
surprising for newcomers, and accidentally shadowing builtins (or not
builtins FWIW) names is a common pitfall. So better to warn newcomers
lurking here !-)
 
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
Re: dict: retrieve the original key by key Christoph Groth Python 5 05-16-2011 12:47 AM
dict: retrieve the original key by key Christoph Groth Python 0 05-15-2011 08:28 AM
dict.keys() and dict.values() are always the same order, is it? Menghan Zheng Python 1 04-20-2010 03:51 AM
dict's as dict's key. Albert van der Horst Python 5 01-17-2010 05:26 PM
dict.items() vs dict.iteritems and similar questions Drew Python 19 03-15-2007 09:23 PM



Advertisments