For a large number of employees, near-optimal might be:
class Company(object):
def __init__(self, name):
self.name = name
self.employee_ids = []
self.employees = {}
self.sorted = True
def addEmployee(self, id, name):
self.employee_ids.append(id)
self.employees[id] = name
self.sorted = False
def displayEmployees(self):
if not self.sorted:
self.employee_ids.sort()
self.sorted = True
for k in self.employee_ids:
print k, '\t', self.employees[k]
This takes O(N)
to insert N
employees -- while keeping the self.employee_ids
sorted with each insertion would make such an operation O(N squared)
. In exchange, this approach makes displayEmployees
worst-case O(N log N)
-- but often better because of the preternaturally good performance of "timsort", Python's sorting algorithm (a variant on natural mergesort) in the real world. For example, if you add just one employee (with a random id that may need to go in the middle) then call displayEmployees
, that's just O(N)
-- timsort magic.
Josh Bloch of "Effective Java" fame, then a Google employee, was at a tech-talk presenting Python's timsort and got, metaphorically speaking:-), struck by lightning on the road to Damascus -- pulled out his laptop (I remember we were both sitting in the front row) and started hacking. Soon after, timsort became the way Java sorts an array of objects, too (alas, not an array of primitives -- for technical reasons, that had to remain a less robust variant of "quicksort").
BTW, timsort is named after its inventor, Tim Peters, also known as "the timbot" in Python circles (being "a bot" in the Python community involves being able to respond to a lot of technical questions, very fast, and usually correctly; Tim was the first one so honored). The second one was F.Lundh, "the effbot". I was later honored to be named the third (and as far as I know last) one, as "the martellibot". However, I've never developed any algorithm one tenth as cool as timsort!-)
TL;DR: using bisect
to maintain a list in sorted order is a classic and apparently cool idea, but, don't do it. I don't recall ever seeing a situation where it was a clear win. Usually, it's best to just append
new stuff to the list, and sort as needed; occasionally, module heapq
in the standard library (with insertions being O(log N)
, not O(N)
like in bisect
) may be better for a peculiar application.
One more note: the self.sorted
flag is a tiny (?) optimization only worth it if you're likely to call displayEmployees
repeatedly with no addEmployee
call in-between; you may well simplify the code by omitting it with no ill effects if such a pattern is not going to happen -- that doesn't change big-O behavior, anyway:-)