Newbie: changing an attribute of objects in a list

Ben Simuyandi 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
if
> > any items have matching .order values, and the object with the larger
.age
> > 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
that
> > 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
(secondary)"
>
> 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)) ]
>     aux.sort()
>     curr_order = aux[0][0]
>     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
.order
> 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.
>
>
> Alex
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>








More information about the Python-list mailing list