Newbie: changing an attribute of objects in a list
bsimuyandi at africonnect.com
Mon Jun 16 11:17:25 CEST 2003
I used this method in the end. It works just as I wanted. Thank you Alex,
and thanks to Steven for helping me out as well.
"Alex Martelli" <aleax at aleax.it> wrote in message
news:1CkGa.85131$pR3.1786454 at news1.tin.it...
> <posted & mailed>
> Ben Simuyandi wrote:
> > I'm very sorry about the confusion. It comes from mistyping, and not
> > thinking through my problem.
> > The first problem is from me not entering the number correctly. As you
> > say, it should be a.order = 8 and g.order =9.
> > As for the second problem, this is because I had not thought about
> > *exactly* what I want. What I would like is for the .age to be compared
> > any items have matching .order values, and the object with the larger
> > value to have its .order value increased by one.
> > for example:
> > if d.order and e.order match
> > compare d.age and e.age
> > if d.age > e.age
> > d.order = d.order + 1
> > else if d.age < e.age
> > e.order = e.order + 1
> > But after that, all objects with a .order value matching or greater than
> > the changed .order value with have to be increased by one as well, so
> > all items still have a unique .order value. I don't actually need to
> > compare .age values any more.
> I suggest you think about the problem in a slightly different way, which
> I believe should produce similar results but in a conceptually simpler
> and speedier way:
> step 1: "sort all objects by increasing order (primary) and age
> step 2: "reassign the values of the order field to ensure uniqueness"
> These two steps would leave your objects sorted by order and age rather
> than in whatever sequence you initially had them in. If that sequence
> is important to you, then you need to keep track of that too, and add
> a third and final step reordering everything in sequence; or else, use
> the indices into the sequence rather than the items themselves, so the
> order of the items never actually gets perturbed.
> Each sorting step should use the DSU (Decorate-Sort-Undecorate) idiom
> that is very well covered in the sorting and searching chapter of the
> Python Cookbook and also exemplified in Python in a Nutshell.
> Here is how I would approach a solution (warning: untested code):
> Prerequisite: the argument items is a nonempty list of objects which have
> comparable fields named age (arbitrary type) and order (integer).
> def updateOrder(items):
> aux = [ (items[i].order, items[i].age, i) for i in range(len(items)) ]
> curr_order = aux
> for order, age, i in aux[1:]:
> if order <= curr_order:
> order = curr_order+1
> items[i].order = order
> curr_order = order
> On exit ensures: the sequence of items is not affected. Each item's
> field is unique within the list. If two items in the list x,y were such
> that x.order < y.order before updateOrder was called, the same condition
> still applies after updateOrder exits. If two items in the list x, y were
> such that x.order == y.order before updateOrder was called, then after
> updateOrder exits x.order < y.order if and only if x.age < y.age, or if
> x.age == y.age and x precedes y in the list's sequence; otherwise (x.age >
> y.age, or x.age == y.age and x follows y in the list's sequence), then
> x.order > y.order after updateOrder exits. No item's .age nor any other
> attribute is modified, except that each item's .order attribute _is_
> modified but only where such modification is indispensable to assure
> the rest of these post-conditions.
More information about the Python-list