简体   繁体   中英

Implementing Merging of List in Python

I am writing a simple program in Python that has to merge two list. I have taken the following pseudocode from An Introduction to Analysis of Algorithm .

合并两个列表的算法

Now I have written following Program in Python.

def merge_list(a,b):
    a,b = sorted(a),sorted(b)
    p1,p2,i = 0,0,0   #python indices start from 0
    c = [0 for x in range(len(a)+len(b))]
    while i<(len(a)+len(b)):

        if a[p1] <= b[p2]:
            c[i] = a[p1]
            p1 = p1 + 1
        else:
            c[i] = b[p1]
            p2 = p2 + 1
        i += 1

    return c
res = merge_list([1,3,5],[2,4,6])

Now I am getting Error with IndexError: list index out of range . Please correct me what I am doing wrong here?

As others have pointed out, you mixed up p1 and p2 . But you also have to check for an empty list, and you also have to account for the possibility that the inputs do not have the same length. This algorithm does not list all of its preconditions, namely, n must be less than or equal to m for it to work as written. So let's take care of that.

>>> def merge_list(a,b):
    a,b = sorted(a),sorted(b)
    if len(a) > len(b):
        a,b = b,a
    p1,p2,i = 0,0,0   #python indices start from 0
    c = [0 for x in range(len(a)+len(b))]
    while i<(len(a)+len(b)):

        if p1<len(a) and p2<len(b) and a[p1] <= b[p2]:
            c[i] = a[p1]
            p1 = p1 + 1
        elif p2<len(b):
            c[i] = b[p2]
            p2 = p2 + 1
        i += 1

    return c

>>> merge_list([1,3,5,7,9],[2,4,6,8])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> merge_list([1,3,5],[2,4,6,7])
[1, 2, 3, 4, 5, 6, 7]

The first three lines of this revised are not strictly from the pseudocode, but otherwise this is a 1-to-1 pairing with the pseudocode.

Note that Sabyasachi's answer is a lot more pythonic and would generally be preferred.

Typo. After the else statement you use p1 to index b

else:
    c[i] = b[p1]
    p2 = p2 + 1

Should be:

else:
    c[i] = b[p2]
    p2 = p2 + 1

Looking at this problem again you also need the length check from Aaron's answer below.

That code doesn't look very pythonic at all. Do something like this.

def merge(a,b):
    c=[]
    while a and b:
            if a[0]<b[0]:
                 c+=a[:1]
                 a=a[1:]
            else:
                 c+=b[:1]
                 b=b[1:]
    return c+a+b

Explanation :It creates a new list c. while a and b checks if both a and b have elements in them. Then it checks which of the first elements is smaller and adds that to c(Note that a[:1] is equivalent to [a[0]] and removes the element from the original list by reassigning it. Finally when it comes out of the loop, one of the lists is empty so the return actually either returns c+a or c+b which is quite intuitively what you would expect merge to return.

You're incrementing p1 beyond a 's range.

You need a check for if you've reached the end of one of the lists.

def merge_list(a,b):
    a,b = sorted(a),sorted(b)
    p1,p2,i = 0,0,0   #python indices start from 0
    c = []
    # first two conditions here are implied.
    while p1 < len(a) and p2 < len(b) and i < (len(a)+len(b)):
        if a[p1] <= b[p2]:
            c.append(a[p1])
            p1 += 1
        else:
            c.append(b[p2])
            p2 += 1
    if p1 >= len(a): # implied 
        while p2 < len(b):
            c.append(b[p2])
            p2 += 1
            i += 1
    if p2 >= len(b): # implied
        while p1 < len(a):
            c.append(a[p1])
            p1 += 1
            i += 1
    i += 1
    return c

res = merge_list([1,3,5,7],[2,4,6,8,10])
print res

prints

[1, 2, 3, 4, 5, 6, 7, 8, 10]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM