[Tutor] Problems with deleting dictionary keys.
dman
dsh8290@rit.edu
Mon, 13 Aug 2001 14:51:15 -0400
On Mon, Aug 13, 2001 at 07:16:55PM +0100, Allan Crooks wrote:
| Hi,
|
| I've got the following problem with dictionaries. The problem is, I get
| this error when I try to delete a key value with the __setitem__
| method.
|
| I feel that the problem will be clearer if I give you example code. :)
|
| -------
|
| Python 2.2a1 (#21, Jul 18 2001, 04:25:46) [MSC 32 bit (Intel)] on
| win32
| Type "copyright", "credits" or "license" for more information.
|
| >>> class d2(dictionary):
| ... def __setitem__(self, key, value):
| ... if value==0:
| ... del self[key]
| ... else:
| ... print "Setting [%s] to %s." % (key, value)
| ...
| >>> d = d2()
| >>> d.update({'p': 1, 'l': 2, 'a': 3, 'i': 4, 'd': 5})
| >>> d
| {'a': 3, 'p': 1, 'i': 4, 'd': 5, 'l': 2}
| >>> d['a']=10
| Setting [a] to 10.
| >>> d['a']=0
| Traceback (most recent call last):
| File "<stdin>", line 1, in ?
| File "<stdin>", line 4, in __setitem__
| SystemError: NULL object passed to Py_BuildValue
The problem is probably that you are destroying the key while at the
same time "creating" it. Notice also that in your __setitem__ method
you never actually set any items. If you tried to 'print d' after the
'd["a"]=10' line you would see that the value hadn't changed.
| I seem to remember there being a problem in earlier versions of
| Python, where if you modify the dictionary while doing other things
| to it, it would crash the interpreter.
Yeah, that was fixed in the new versions though. I think it was
something like if you were iterating over the dictionary and removed a
key it would have problems, or something like that.
| So what I need to know is if this is a bug, or if I'm doing something
| wrong....
I think you want something similar to UserDict :
def __getitem__(self, key): return self.data[key]
def __setitem__(self, key, item): self.data[key] = item
def __delitem__(self, key): del self.data[key]
Either you could write this yourself in your class or you could
inherit from UserDict which is probably what you want.
The proper way to delete a dictionary key is with the 'del' keyword :
>>> d = {}
>>> print d
{}
>>> d[ 'a' ] = 10
>>> print d
{'a': 10}
>>> del d[ 'a' ]
>>> print d
{}
>>>
>>> import UserDict
>>> d2 = UserDict.UserDict()
>>> print d2
{}
>>> d2[ 'a' ] = 10
>>> print d2
{'a': 10}
>>> del d2[ 'a' ]
>>> print d2
{}
>>>
HTH,
-D