Newbie: changing an attribute of objects in a list

Steven Taschuk staschuk at
Wed Jun 11 20:06:56 CEST 2003

Quoth Ben Simuyandi:
> OK, I've read a bit and I've now changed the code. If anyone would like to
> give feedback (better ways of doing it, where am I going wrong) that would
> be appreciated:

It would be nice to see an example list of objects and the desired
result for that list.

Without that, here's one possible, simple-minded and completely
untested notion:

    # separate items into groups by x.order
    d = {}
    for x in items:
        d.setdefault(x.order, []).append(x)

    # resolve conflicts
    orders = d.keys()
    for order in orders:
        # sort descending by age
        assert len(d[order]) > 0
        decorated = [(x.age, -i, x) for x in enumerate(d[order])]
        sorted = [x for _, _, x in decorated]
        del decorated

        # Replace the list d[order] with its oldest element.
        # Put the remaining elements, in reverse order of age, into
        # d[order+1], d[order+2], etc.
        # If one of those is found already to have elements,
        # just dump all the remaining elements in that list; the
        # loop over the orders will then pick up at that point.

        # (Note how this makes it okay to be mutating the dict and
        # iterating over an independent list of the original keys.)

        del d[order]
        for i, x in enumerate(sorted):
            if order+i not in d:
                d[order+i] = x

    # assign .order attributes
    for order, x in d.iteritems():
        x.order = order

This uses enumerate(), a new built-in in Python 2.3; in 2.2 you
can write it yourself, like this:

    from __future__ import generators

    def enumerate(items):
        i = 0
        for x in items:
            yield i, x
            i = i + 1

Steven Taschuk                staschuk at
"I tried to be pleasant and accommodating, but my head
 began to hurt from his banality."   -- _Seven_ (1996)

More information about the Python-list mailing list