On Fri, 6 Feb 2009, greyw...@gmail.com wrote: > On Jan 28, 4:37 am, John O'Hagan <m...@johnohagan.com> wrote: > > On Tue, 27 Jan 2009, Reckoner wrote: > > > I'm not sure this is possible, but I would like to have > > > a list of objects > > > > > > A=[a,b,c,d,...,z] > > > > > > where, in the midst of a lot of processing I might do something like, > > > > > > A[0].do_something_which_changes_the_properties() > > > > > > which alter the properties of the object 'a'. > > > > > > The trick is that I would like A to be mysteriously aware that > > > something about the object 'a' has changed so that when I revisit A, > > > I will know that the other items in the list need to be refreshed to > > > reflect the changes in A as a result of changing 'a'. > > > > > > Even better would be to automatically percolate the subsequent changes > > > that resulted from altering 'a' for the rest of the items in the list. > > > > [...] > > > > Interesting question. > > > > Maybe this is too simple for your purpose (or maybe just wrong!), but > > could you subclass list and give it an "update" method which keeps a > > dictionary of the state of its members and/or calls another method that > > makes the appropriate changes in the other members when a change occurs, > > something like: > > > > class SelfAwareList(list): > > > > state_dict = {} > > > > def update(self): > > for i in self: > > if i.state == 'some_condition': > > self.do_stuff_to_other_members() > > self.state_dict[i] = i.state > > > > def do_stuff_to_other_members(self): > > print 'doing stuff...' > > > > ? > > > > You could manually call update() on the SelfAwareList instance after > > calling a method on a SelfAwareList member, or even build it into the > > members' methods so that it was automatic. > > > > HTH, > > > > John > > Hi Reckoner & John O'Hagan, > > Great thread, very interesting. > > John, I haven't seen anything like your class that uses list instead > of object and refers to state directly (i.state in self). Could you > elaborate? Here would be my implementation of your idea: > > class SelfAwareList2(object): > > def __init__(self, l): > self.l = l > self.changed = [False for element in l] > > def __str__(self): > return str(self.l) > > def update(self, index, value): > self.l[index] = value > self.changed[index] = True > > def do_stuff_to_other_members(self): > for i in self.changed: > if i==False: > self.l[i] += 1 > > Here you can print and whenever you update your list, self.changed > keeps track of what changed. Later on you can call do_stuff_to_others > which in this case adds 1 to each other element. > > I assume that your class replaces the awkwardness of l.update(0, 5) > with l[0] = 5, but I can't quite wrap my mind around it.
I think my suggestion was much more simplistic than what the OP was after, which was far more thoroughly answered by others. But as far as my version goes, your implementation is fine as far as I can tell; although I (possibly mistakenly) interpreted the OP as wanting something which kept track of _how_ the items in the list changed, not just _if_ they changed. Trying to put together an example was (naturally) more complicated than I thought, but here's a silly one, with apologies to Steven D'Aprano among others for stealing the parrot theme: class Parrot(object): def __init__(self, name): self.color = 'red' self.name = name def __repr__(self): return self.name class SelfAwareListOfParrots(list): colors = ['red', 'blue', 'yellow', 'green', 'black', 'white'] state_dict = {} def update(self, changed=None): """Ensure no duplicate colors and record changes""" for parrot in self: used_colors = [parrot.color for parrot in self] available_colors = [color for color in self.colors if color not in used_colors] if (parrot is not changed and used_colors.count(parrot.color) > 1): parrot.color = available_colors[0] self.state_dict[parrot] = parrot.color def change(self, parrot, color): """Change color and update""" self[self.index(parrot)].color = color self.update(parrot) This list knows when a parrot has had its color changed by calling change() on the list, and makes sure no parrots are the same color by changing any parrots of duplicate color. It has a state_dict attribute (redundant in this example) which keeps track of the colors after an update. (My version of the update method updates the whole list). The trick is to have the method that changes the elements of the list defined in the list class definition, rather than that of the elements' class, that way it's easy for the list to know about changes to its elements. (If a parrots color is changed directly, update() will still ensure unique colors, but will not preserve the change unless that parrot is given as an argument.) For example: polly = Parrot('polly') molly = Parrot('molly') dolly = Parrot('dolly') salp = SelfAwareListOfParrots([polly, molly, dolly]) print salp.state_dict >>>{molly: 'yellow', polly: 'white', dolly: 'black'} salp.change(polly, 'black') print salp.state_dict >>>{molly: 'yellow', polly: 'black', dolly: 'white'} As for the subclassing of list, that allows you to create a class with all the methods of a list, to which you can add your own. (Although any list methods which return a new list will return a list, not an instance of your class, unless you define them to do so in your class definition). In my post quoted above, by "i.state" I was probably abusing the term "state" to signify "some arbitrary attribute" of i. I'm pretty new to this stuff, but there are plenty of tutorials on it out there, and I'm relying on others to correct any fallacies I may be unwittingly propagating here. :) Regards, John -- http://mail.python.org/mailman/listinfo/python-list