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

Discussion in 'Python' started by rodrigo, Aug 28, 2007.

  1. rodrigo

    rodrigo Guest

    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
    rodrigo, Aug 28, 2007
    #1
    1. Advertising

  2. 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
    Bruno Desthuilliers, Aug 28, 2007
    #2
    1. Advertising

  3. rodrigo

    Jason Guest

    On Aug 28, 8:36 am, rodrigo <> 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"
    Jason, Aug 28, 2007
    #3
  4. rodrigo

    Evan Klitzke Guest

    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 <>
    Evan Klitzke, Aug 28, 2007
    #4
  5. rodrigo

    rodrigo Guest

    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!
    rodrigo, Aug 28, 2007
    #5
  6. rodrigo

    rodrigo Guest

    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
    rodrigo, Aug 28, 2007
    #6
  7. rodrigo

    Ben Finney Guest

    rodrigo <> 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
    Ben Finney, Aug 29, 2007
    #7
  8. rodrigo

    Ben Finney Guest

    Ben Finney <> 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
    Ben Finney, Aug 29, 2007
    #8
  9. rodrigo

    Dustan Guest

    On Aug 28, 1:13 pm, rodrigo <> 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.
    Dustan, Aug 29, 2007
    #9
  10. 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 !-)
    Bruno Desthuilliers, Aug 29, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jaap de verwant slachter
    Replies:
    0
    Views:
    1,240
    jaap de verwant slachter
    Jul 1, 2003
  2. Roy in

    need step by step example

    Roy in, Aug 3, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    341
    Roy in
    Aug 3, 2003
  3. Steve Richter

    a step by step page

    Steve Richter, May 3, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    362
    Steve Richter
    May 3, 2005
  4. craig dicker
    Replies:
    1
    Views:
    341
    Peter Rilling
    Jul 10, 2005
  5. Albert van der Horst

    dict's as dict's key.

    Albert van der Horst, Jan 13, 2010, in forum: Python
    Replies:
    5
    Views:
    246
    Lie Ryan
    Jan 17, 2010
Loading...

Share This Page