Just like in a normal text editor,
I would like to detect if a dictionary has been changed.
So I would like to have a modified-flag.
(This dictionary is used as a communication channel between processes)
Now I do it to make a copy of the dictionary and compare it with the old
one.
When a change is detected I nake a new copy and interpret the whole new
dictionary again,
so I'm not interested in knowing where the change(s) are located.
This works well, but as I have many of these dictionaries,
I find the copy a waste of time and space.
Has anyone derived a new dictionary with a modified flag ?
Or are there other solutions to detect easily a directory change ?
thanks,
Stef Mientki
A solution is of course to create a SDict class, that works like a
normal dict, and also watches for changes and has an extra boolean
attribute.
Bye,
bearophile
What does the S stand for?
Untested and possibly incomplete:
def factory(methodname, cls=dict, flag=True):
def method(self, *args, **kwargs):
self.modified = flag
return getattr(cls, methodname)(self, *args, **kwargs)
return method
class SDict(dict):
__init__ = factory('__init__', flag=False)
__setitem__ = factory('__setitem__')
__delitem__ = factory('__delitem__')
clear = factory('clear')
pop = factory('pop')
popitem = factory('popitem')
setdefault = factory('setdefault')
update = factory('update')
--
Steven
cheers,
Stef
As a couple of people have said, you could make a dict subclass that
notices when you do updates. I think the real answer is a
"functional" dictionary, which means one that is never updated. You
instead make a new functional dictionary that shares structure with
the old one. The functional dictionary uses a balanced-tree data
structure that makes this creation of new partially-shared
dictionaries efficient. Look up "AVL tree" or "red-black tree" for
how they work.
I've been wanting for a while to get around to coding some of these
structures in Python, but I'll be even happier if someone else beats
me to it.
Python V. 2.4, 2.5, 2.6. 3.0 have gained more and more lazy-style
features, this is changing a little how normal Python programs are
written (compared for example with Haskell, using lazy computations in
Python is less handy and probably less safe too, because for example
in Haskell you can define something that lazily generates an infinite
sequence of items, this is now easy to do in Python too, but in
Haskell inside the generator you can use items generated in the past
too, and the generators don't exhaust).
In the last years functional languages are raising their elegant
lambda-shaped heads more and more, so today you can find several
immutable data structures in Scala and F# languages (and in the D
language true closures, simple ways to state recursively immutable
things, and even pure functions. This will make D like a cleaned up,
simplified and improved C++ with functional features added. Then D3
may add AST macros. At that point pattern-matching programming,
dataflow programming, constraint programming and Logic programming
become the few programming styles not supported natively).
So maybe in the following years Python too may gain few other
immutable data structures, fitter for a functional style of
programming (in Python there are already some immutable data
structures, like strings, tuples, frozensets, and I sometimes use
frozendicts. Time objects and time deltas too are often good kept as
immutable).
Bye,
bearophile
The S stands for simple.
http://wanderingbarque.com/nonintersecting/2006/11/15/the-s-stands-for-simple/
Stefan
Interesting technique. I must point out, though, that it doesn't
indicate if a dict has been changed, only that potentially changing
operations have been performed. So it really depends on what Stef
originally meant by changed, and perhaps what is meant by == :)
x = {'a', 3}
x['a'] = 3
Whether x has been changed by the second statement is the open
question. The above code would declare it has, but most people, when
shown before and after copies of the dict, with declare it hasn't.
--
Glenn -- http://nevcal.com/
===========================
A protocol is complete when there is nothing left to remove.
-- Stuart Cheshire, Apple Computer, regarding Zero Configuration Networking
You mean x = {'a': 3}!
> x['a'] = 3
>
> Whether x has been changed by the second statement is the open
> question. The above code would declare it has, but most people, when
> shown before and after copies of the dict, with declare it hasn't.
Good point. What about
>>> d = {1: []}
>>> d[1].append(2)
Has d changed or not?
--
Arnaud
> Interesting technique. I must point out, though, that it doesn't
> indicate if a dict has been changed, only that potentially changing
> operations have been performed.
[...]
> The above code would declare it has, but most people, when shown before
> and after copies of the dict, with declare it hasn't.
Oh I agree entirely. But I'm not going to do *all* the work for the
original poster :)
--
Steven
Indeed I did, thanks for the correction.
>> x['a'] = 3
>>
>> Whether x has been changed by the second statement is the open
>> question. The above code would declare it has, but most people, when
>> shown before and after copies of the dict, with declare it hasn't.
>>
>
> Good point. What about
>
>
>>>> d = {1: []}
>>>> d[1].append(2)
>>>>
>
> Has d changed or not?
>
Which just goes to show that the SDict implementation above is, as
suspected by the author, incomplete for the purpose of detecting all
changes to the dict, as well as detecting some that might not be
perceived as changes.
thank you all for the contributions.
Paul and "bearophile", you talks about "functional" languages and
balanced trees are a bit too high for my knowledge,
all though the program in which I need this is a functional language
environment and based on dataflow programming ;-)
cheers,
stef