Newbie: changing an attribute of objects in a list

Steven Taschuk staschuk at telusplanet.net
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()
orders.sort()
for order in orders:
# sort descending by age
assert len(d[order]) > 0
decorated = [(x.age, -i, x) for x in enumerate(d[order])]
decorated.sort()
decorated.reverse()
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
else:
d[order+i].extend(sorted[i:])
break

# 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 telusplanet.net
"I tried to be pleasant and accommodating, but my head
began to hurt from his banality."   -- _Seven_ (1996)

```