python - Vectorising a decrement operation on a list of objects -
is there pythonic/efficient way carry out simple decrement operation on each element (or more accurately subset of elements) in list of objects of arbitrary class?
i potentially have large-ish (~ 10k) list of objects, each of updated periodically on basis of countdown "time update" (ttu) value.
the simple way handle decrement value in each element below:
def batesnumber(start = 0): n = start while true: yield n n += 1 class foo: index = batesnumber() def __init__(self, ttu): self.id = next(foo.index) self.time = ttu self.ttu = ttu def __repr__(self): return "#{}:{}/{}".format(self.id, self.ttu, self.time) def decrement(self): self.ttu -= 1 def reset(self): print("reset {} {}".format(self.id, self.time)) self.ttu = self.time def isreadyforupdate(self): if self.ttu == 0: return true else: return false bar = [foo(i) in range(10, 20, 2)] n in range(50): p in bar: if p.isreadyforupdate(): print("{} {}".format(n, p)) p.reset() else: p.decrement()
so guess after pythonic way of "vectorising" decrement operation - i.e. decrement elements in list in suitably elegant way; and, ideally, returning elements require update/reset.
i (although seems bit unnecessarily horrible) produce list ordered on ttu value, , have ttu values relative neighbour. way require 1 decrement per cycle, when reset counter have pain of rebuilding list. suppose better long list quite high ttu values.
i presume best/pythonic way check of elements ready update using list comprehension.
any advice?
perhaps replace flat list priority queue using heapq
module. priorities current time, plus object's ttu
. when current time matched top element's priority, you'd pop off, whatever updating was, , push queue new priority.
the code this:
import heapq items = [foo(i) in range(10,20)] queue = [(f.ttu, f.id, f) f in items] heapq.heapify(queue) t in range(50): while t >= queue[0][0]: _, _, f = heapq.heappop(queue) # update f here heapq.heappush(queue, (t + f.ttu, f.id, f))
i'm using object's id
attribute tie breaker when 2 objects need updated @ same time. if wanted to, make priority queue implementation easier implementing __lt__
operator in objects allow them compared directly. if made them track own update times, queue contain objects directly (like items
list) rather tuples make them sort in order of priority.
something like:
class foo: index = batesnumber() def __init__(self, ttu): self.id = next(index) self.next_update = ttu self.ttu = ttu def __lt__(self, other): return (self.next_update, self.id) < (other.next_update, other.id) # ideally you'd write __eq__, __gt__, etc. methods, heapq needs __lt__ def update(self): self.next_update += self.ttu # maybe other update stuff here?
by way, batesnumber
class identical itertools.count
.
Comments
Post a Comment