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

R

rodrigo

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
 
B

Bruno Desthuilliers

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
 
J

Jason

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

--Jason

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

Evan Klitzke

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!
 
R

rodrigo

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

Thanks!
 
R

rodrigo

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
 
B

Ben Finney

rodrigo said:
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.
 
B

Ben Finney

Ben Finney said:
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
 
D

Dustan

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

Thanks!

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

Bruno Desthuilliers

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 !-)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top