Merge sorted lists in python

前端 未结 9 983
花落未央
花落未央 2020-12-19 00:50

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         


        
相关标签:
9条回答
  • 2020-12-19 01:16

    Below is an example of a function that runs in O(n) comparisons.

    You could make this faster by making a and b iterators and incrementing them.

    I have simply called the function twice to merge 3 lists:

    def zip_sorted(a, b):
        '''
        zips two iterables, assuming they are already sorted
        '''
        i = 0
        j = 0
        result = []
        while i < len(a) and j < len(b):
            if a[i] < b[j]:
                result.append(a[i])
                i += 1
            else:
                result.append(b[j])
                j += 1
        if i < len(a):
            result.extend(a[i:])
        else:
            result.extend(b[j:])
        return result
    
    def genSortedList(num,seed):
        result = [] 
        for i in range(num):
            result.append(i*seed)
        return result
    
    if __name__ == '__main__':
        a = genSortedList(10000,2.0)
        b = genSortedList(6666,3.0)
        c = genSortedList(5000,4.0)
        d = zip_sorted(zip_sorted(a,b),c)
        print d
    

    However, heapq.merge uses a mix of this method and heaping the current elements of all lists, so should perform much better

    0 讨论(0)
  • 2020-12-19 01:17

    Python standard library offers a method for it: heapq.merge.
    As the documentation says, it is very similar to using itertools (but with more limitations); if you cannot live with those limitations (or if you do not use Python 2.6) you can do something like this:

    sorted(itertools.chain(args), cmp)
    

    However, I think it has the same complexity as your own solution, although using iterators should give some quite good optimization and speed increase.

    0 讨论(0)
  • 2020-12-19 01:19

    I like Roberto Liffredo's answer. I didn't know about heapq.merge(). Hmmmph.

    Here's what the complete solution looks like using Roberto's lead:

    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
    
    a = [Obj(1), Obj(3), Obj(8)]
    b = [Obj(1), Obj(2), Obj(3)]
    c = [Obj(100), Obj(300), Obj(800)]
    
    import heapq
    
    sorted = [item for item in heapq.merge(a,b,c)]
    for item in sorted:
        print item
    

    Or:

    for item in heapq.merge(a,b,c):
        print item
    
    0 讨论(0)
提交回复
热议问题