I have a bunch of sorted lists of objects, and a comparison function
class Obj :
def __init__(p) :
self.points = p
def cmp(a, b) :
return a.p
I asked a similar question and got some excellent answers:
The best solutions from that question are variants of the merge algorithm, which you can read about here:
Use the bisect module. From the documentation: "This module provides support for maintaining a list in sorted order without having to sort the list after each insertion."
import bisect
def magic(*args):
r = []
for a in args:
for i in a:
bisect.insort(r, i)
return r
Here you go: a fully functioning merge sort for lists (adapted from my sort here):
def merge(*args):
import copy
def merge_lists(left, right):
result = []
while left and right:
which_list = (left if left[0] <= right[0] else right)
result.append(which_list.pop(0))
return result + left + right
lists = list(args)
while len(lists) > 1:
left, right = copy.copy(lists.pop(0)), copy.copy(lists.pop(0))
result = merge_lists(left, right)
lists.append(result)
return lists.pop(0)
Call it like this:
merged_list = merge(a, b, c)
for item in merged_list:
print item
For good measure, I'll throw in a couple of changes to your Obj class:
class Obj(object):
def __init__(self, p) :
self.points = p
def __cmp__(self, b) :
return cmp(self.points, b.points)
def __str__(self):
return "%d" % self.points
self
to __init__()
__cmp__
a member functionstr()
member function to present Obj
as stringInstead of using a list, you can use a [heap](http://en.wikipedia.org/wiki/Heap_(data_structure).
The insertion is O(log(n)), so merging a, b and c will be O(n log(n))
In Python, you can use the heapq module.
One line solution using sorted:
def magic(*args):
return sorted(sum(args,[]), key: lambda x: x.points)
IMO this solution is very readable.
Using heapq module, it could be more efficient, but I have not tested it. You cannot specify cmp/key function in heapq, so you have to implement Obj to be implicitly sorted.
import heapq
def magic(*args):
h = []
for a in args:
heapq.heappush(h,a)
return [i for i in heapq.heappop(h)
I don't know whether it would be any quicker, but you could simplify it with:
def GetObjKey(a):
return a.points
return sorted(a + b + c, key=GetObjKey)
You could also, of course, use cmp
rather than key
if you prefer.