[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