My implementation of merging two sorted lists in linear time - what could be improved?

后端 未结 9 595
忘掉有多难
忘掉有多难 2021-01-01 04:47

Fromg Google\'s Python Class:

E. Given two lists sorted in increasing order, create and return a merged
list of all the elements in sorted order. You may mod         


        
9条回答
  •  耶瑟儿~
    2021-01-01 04:56

    Here's a generator approach. You've probably noticed that a whole lot of these "generate lists" can be done well as generator functions. They're very useful: they don't require you to generate the whole list before using data from it, to keep the whole list in memory, and you can use them to directly generate many data types, not just lists.

    This works if passed any iterator, not just lists.

    This approach also passes one of the more useful tests: it behaves well when passed an infinite or near-infinite iterator, eg. linear_merge(xrange(10**9), xrange(10**9)).

    The redundancy in the two cases could probably be reduced, which would be useful if you wanted to support merging more than two lists, but for clarity I didn't do that here.

    def linear_merge(list1, list2):
        """
        >>> a = [1, 3, 5, 7]
        >>> b = [2, 4, 6, 8]
        >>> [i for i in linear_merge(a, b)]
        [1, 2, 3, 4, 5, 6, 7, 8]
        >>> [i for i in linear_merge(b, a)]
        [1, 2, 3, 4, 5, 6, 7, 8]
        >>> a = [1, 2, 2, 3]
        >>> b = [2, 2, 4, 4]
        >>> [i for i in linear_merge(a, b)]
        [1, 2, 2, 2, 2, 3, 4, 4]
        """
        list1 = iter(list1)
        list2 = iter(list2)
    
        value1 = next(list1)
        value2 = next(list2)
    
        # We'll normally exit this loop from a next() call raising StopIteration, which is
        # how a generator function exits anyway.
        while True:
            if value1 <= value2:
                # Yield the lower value.
                yield value1
                try:
                    # Grab the next value from list1.
                    value1 = next(list1)
                except StopIteration:
                    # list1 is empty.  Yield the last value we received from list2, then
                    # yield the rest of list2.
                    yield value2
                    while True:
                        yield next(list2)
            else:
                yield value2
                try:
                    value2 = next(list2)
    
                except StopIteration:
                    # list2 is empty.
                    yield value1
                    while True:
                        yield next(list1)
    

提交回复
热议问题