Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > no-clobber dicts?

Reply
Thread Tools

no-clobber dicts?

 
 
kj
Guest
Posts: n/a
 
      08-03-2009




I use the term "no-clobber dict" to refer to a dictionary D with
the especial property that if K is in D, then

D[K] = V

will raise an exception unless V == D[K]. In other words, D[K]
can be set if K doesn't exist already among D's keys, or if the
assigned value is equal to the current value of D[K]. All other
assignments to D[K] trigger an exception.

The idea here is to detect inconsistencies in the data.

This is a data structure I often need. Before I re-invent the
wheel, I thought I'd ask: is it already available?

TIA!

kynn
 
Reply With Quote
 
 
 
 
r
Guest
Posts: n/a
 
      08-03-2009
On Aug 3, 4:07*pm, kj <(E-Mail Removed)> wrote:
> I use the term "no-clobber dict" to refer to a dictionary D with
> the especial property that if K is in D, then
>
> * D[K] = V
>
> will raise an exception unless V == D[K]. *In other words, D[K]
> can be set if K doesn't exist already among D's keys, or if the
> assigned value is equal to the current value of D[K]. *All other
> assignments to D[K] trigger an exception.
>
> The idea here is to detect inconsistencies in the data.
>
> This is a data structure I often need. *Before I re-invent the
> wheel, I thought I'd ask: is it already available?
>
> TIA!
>
> kynn


Not sure if something like this already exists, but it would be
trivial to implement by overriding dict.__setitem__()

badda-bing baby!
 
Reply With Quote
 
 
 
 
Chris Rebert
Guest
Posts: n/a
 
      08-03-2009
On Mon, Aug 3, 2009 at 2:47 PM, r<(E-Mail Removed)> wrote:
> On Aug 3, 4:07*pm, kj <(E-Mail Removed)> wrote:
>> I use the term "no-clobber dict" to refer to a dictionary D with
>> the especial property that if K is in D, then
>>
>> * D[K] = V
>>
>> will raise an exception unless V == D[K]. *In other words, D[K]
>> can be set if K doesn't exist already among D's keys, or if the
>> assigned value is equal to the current value of D[K]. *All other
>> assignments to D[K] trigger an exception.
>>
>> The idea here is to detect inconsistencies in the data.
>>
>> This is a data structure I often need. *Before I re-invent the
>> wheel, I thought I'd ask: is it already available?
>>
>> TIA!
>>
>> kynn

>
> Not sure if something like this already exists, but it would be
> trivial to implement by overriding dict.__setitem__()


That is, if you don't care about .update() not preserving the
invariant. Otherwise, one will need to look at the UserDict module.

Cheers,
Chris
--
http://blog.rebertia.com
 
Reply With Quote
 
r
Guest
Posts: n/a
 
      08-03-2009
On Aug 3, 5:00*pm, Chris Rebert <(E-Mail Removed)> wrote:
> On Mon, Aug 3, 2009 at 2:47 PM, r<(E-Mail Removed)> wrote:

[snip]
> > Not sure if something like this already exists, but it would be
> > trivial to implement by overriding dict.__setitem__()

>
> That is, if you don't care about .update() not preserving the
> invariant. Otherwise, one will need to look at the UserDict module.
>
> Cheers,
> Chris
> --http://blog.rebertia.com


Good catch Chris. However since the OP said this was for testing
purposes, i just *assumed* he would be smart enough *not* to call
update() on the dict at hand . But sometimes i need to be protected
from myself too -- at least thats what my therapist keeps telling
me



 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      08-04-2009
On Mon, 03 Aug 2009 21:07:32 +0000, kj wrote:

> I use the term "no-clobber dict" to refer to a dictionary D with the
> especial property that if K is in D, then
>
> D[K] = V
>
> will raise an exception unless V == D[K]. In other words, D[K] can be
> set if K doesn't exist already among D's keys, or if the assigned value
> is equal to the current value of D[K]. All other assignments to D[K]
> trigger an exception.



Coincidentally, I just built something very close to what you ask. Here
it is:

class ConstantNamespace(dict):
"""Dictionary with write-once keys."""
def __delitem__(self, key):
raise TypeError("can't unbind constants")
def __setitem__(self, key, value):
if key in self:
raise TypeError("can't rebind constants")
super(ConstantNamespace, self).__setitem__(key, value)
def clear(self):
raise TypeError('cannot unbind constants')
def pop(self, key, *args):
raise TypeError("cannot pop constants")
def popitem(self):
raise TypeError("cannot pop constants")
def update(self, other):
for key in other:
if key in self:
raise TypeError('cannot update constants')
# If we get here, then we're not modifying anything,
# so okay to proceed.
super(ConstantNamespace, self).update(other)
def copy(self):
c = self.__class__(**self)
return c



I also have a series of unit tests for it if you're interested in them.




--
Steven
 
Reply With Quote
 
alex23
Guest
Posts: n/a
 
      08-04-2009
Steven D'Aprano <(E-Mail Removed)> wrote:
> I also have a series of unit tests for it if you're interested in them.


That's several times today that kj has asked a question and you've
responded with ready-to-go code. If this was Stackoverflow, I'd accuse
you of reputation-whoring...

You _can_ just post your cool code without the double act, y'know!
 
Reply With Quote
 
kj
Guest
Posts: n/a
 
      08-04-2009
In <(E-Mail Removed) om.au> Steven D'Aprano <(E-Mail Removed)> writes:

>On Mon, 03 Aug 2009 21:07:32 +0000, kj wrote:


>> I use the term "no-clobber dict" to refer to a dictionary D with the
>> especial property that if K is in D, then
>>
>> D[K] = V
>>
>> will raise an exception unless V == D[K]. In other words, D[K] can be
>> set if K doesn't exist already among D's keys, or if the assigned value
>> is equal to the current value of D[K]. All other assignments to D[K]
>> trigger an exception.



>Coincidentally, I just built something very close to what you ask. Here
>it is:


>class ConstantNamespace(dict):
> """Dictionary with write-once keys."""
> def __delitem__(self, key):
> raise TypeError("can't unbind constants")
> def __setitem__(self, key, value):
> if key in self:
> raise TypeError("can't rebind constants")
> super(ConstantNamespace, self).__setitem__(key, value)
> def clear(self):
> raise TypeError('cannot unbind constants')
> def pop(self, key, *args):
> raise TypeError("cannot pop constants")
> def popitem(self):
> raise TypeError("cannot pop constants")
> def update(self, other):
> for key in other:
> if key in self:
> raise TypeError('cannot update constants')
> # If we get here, then we're not modifying anything,
> # so okay to proceed.
> super(ConstantNamespace, self).update(other)
> def copy(self):
> c = self.__class__(**self)
> return c



Thanks. As you note this not quite what I'm looking for, but it's
a good template for it.

kynn
 
Reply With Quote
 
kj
Guest
Posts: n/a
 
      08-04-2009
In <(E-Mail Removed)> Chris Rebert <(E-Mail Removed)> writes:

>On Mon, Aug 3, 2009 at 2:47 PM, r<(E-Mail Removed)> wrote:
>> On Aug 3, 4:07=C2=A0pm, kj <(E-Mail Removed)> wrote:
>>> I use the term "no-clobber dict" to refer to a dictionary D with
>>> the especial property that if K is in D, then
>>>
>>> =C2=A0 D[K] =3D V
>>>
>>> will raise an exception unless V =3D=3D D[K]. =C2=A0In other words, D[K]
>>> can be set if K doesn't exist already among D's keys, or if the
>>> assigned value is equal to the current value of D[K]. =C2=A0All other
>>> assignments to D[K] trigger an exception.
>>>
>>> The idea here is to detect inconsistencies in the data.
>>>
>>> This is a data structure I often need. =C2=A0Before I re-invent the
>>> wheel, I thought I'd ask: is it already available?
>>>
>>> TIA!
>>>
>>> kynn

>>
>> Not sure if something like this already exists, but it would be
>> trivial to implement by overriding dict.__setitem__()


>That is, if you don't care about .update() not preserving the
>invariant.


The implication here is that .update() does not in turn use
..__setitem__(), which I find a bit surprising.

kynn
 
Reply With Quote
 
kj
Guest
Posts: n/a
 
      08-04-2009
In <(E-Mail Removed) om.au> Steven D'Aprano <(E-Mail Removed)> writes:

>class ConstantNamespace(dict):

<snip>

>I also have a series of unit tests for it if you're interested in them.


Actually, come to think of it, I think I'll take you up on this.
I'd love to see those tests. Unit testing in Python is in area I
need to work on.

TIA!

kynn
 
Reply With Quote
 
Chris Rebert
Guest
Posts: n/a
 
      08-04-2009
On Tue, Aug 4, 2009 at 12:30 PM, kj<(E-Mail Removed)> wrote:
> In <(E-Mail Removed)> Chris Rebert <(E-Mail Removed)> writes:
>
>>On Mon, Aug 3, 2009 at 2:47 PM, r<(E-Mail Removed)> wrote:
>>> On Aug 3, 4:07=C2=A0pm, kj <(E-Mail Removed)> wrote:
>>>> I use the term "no-clobber dict" to refer to a dictionary D with
>>>> the especial property that if K is in D, then
>>>>
>>>> =C2=A0 D[K] =3D V
>>>>
>>>> will raise an exception unless V =3D=3D D[K]. =C2=A0In other words, D[K]
>>>> can be set if K doesn't exist already among D's keys, or if the
>>>> assigned value is equal to the current value of D[K]. =C2=A0All other
>>>> assignments to D[K] trigger an exception.
>>>>
>>>> The idea here is to detect inconsistencies in the data.
>>>>
>>>> This is a data structure I often need. =C2=A0Before I re-invent the
>>>> wheel, I thought I'd ask: is it already available?
>>>>
>>>> TIA!
>>>>
>>>> kynn
>>>
>>> Not sure if something like this already exists, but it would be
>>> trivial to implement by overriding dict.__setitem__()

>
>>That is, if you don't care about .update() not preserving the
>>invariant.

>
> The implication here is that .update() does not in turn use
> .__setitem__(), which I find a bit surprising.


The builtin types are allowed to take such shortcuts for performance reasons.

Cheers,
Chris
--
http://blog.rebertia.com
 
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




Advertisments