Reputation: 1637
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?
Upvotes: 0
Views: 420
Reputation: 395015
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]
Upvotes: 2
Reputation: 624
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.
Upvotes: 3
Reputation: 11026
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.
Upvotes: 4
Reputation: 63
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.
Upvotes: 3