Reputation: 403
I'm trying to make a merge function that will be used in the merge sort that I'm making.
I have run into some trouble, and I can't seem to find the error.
I commented it to try to show you guys my thought process:
def merge(aList, bList):
newList = []
while (len(aList) > 0) & (len(bList) > 0): #Loop until both lists are empty
if aList[0] < bList[0]: #If the first item of aList is smaller than the first item of bList
newList.append(aList[0]) #add that item to the new list
aList.pop(0) #and remove it from the original list
else: #If it gets here, that means the first item of bList was smaller
newList.append(bList[0]) #So put the first item of bList is the new list
bList.pop(0) #and remove it from the original
return newList
list1 = [3, 4, 8, 9]
list2 = [1, 2, 5, 8]
print(merge(list1, list2))
print(list1)
print(list2)
Output:
[1, 2, 3, 4, 5, 8]
[8, 9]
[0]
I was expecting list1 and list2 to be empty, but for some reason there appears to be an un-placed 8 and 9 in list1. Anyone have ideas?
Upvotes: 6
Views: 2795
Reputation: 2444
This alternative follows @Reut Sharabani idea about handle empty lists but I simply decided to pop the smallest numbers until empty anyone and add the other (remaining) to the end.
def merge_sorted_lists(list1,list2):
new_sorted = []
# select the smallest number in current lists until empty any list
while len(list1 and list2):
toadd = list1.pop(0) if (list1[0]<=list2[0]) else list2.pop(0) # select the smaller number
new_sorted.append(toadd)
remaining = list1 if (not list2) else list2
new_sorted += remaining # the remaining is always greater and sorted
return new_sorted
list1, list2 = [35, 36, 46, 82, 92], [0, 11, 15, 22, 22, 33, 35, 53, 59, 61, 74, 76]
print(merge_sorted_lists(list1,list2))
Upvotes: 0
Reputation: 499
Not the best solution but I encountered to same problem today;
def merge(str1, str2):
j = 0
for i in range(len(str2)):
while(j < len(str1) and str2[i] > str1[j]):
j += 1
str1.insert(j, str2[i])
return str1
Upvotes: 0
Reputation: 31349
Make sure you keep adding elements even if a list is out of elements. Your current code stops once either aList
or bList
is empty, which is probably not what you want.
You can do this by using the fact that an empty list is evaluated as False
using an if
expression:
def merge(aList, bList):
newList = []
while (aList or bList): # single empty list won't stop the loop
if not bList or (aList and aList[0] < bList[0]):
# either bList is empty, or aList has next item
newList.append(aList.pop(0))
else:
# bList has next item
newList.append(bList.pop(0))
reutrn newList
list1 = [3, 4, 8, 9]
list2 = [1, 2, 5, 8]
print(merge(list1, list2))
print(list1)
print(list2)
Output:
sh-4.2# python3 main.py
[1, 2, 3, 4, 5, 8, 8, 9]
[]
[]
Upvotes: 2
Reputation: 966
This isn't the most elegant of solutions however it does show all of the possible conditions and solves the problem at hand and should help provide an understanding of the logic of the merge operation.
def merge(a, b):
newList = []
while(len(a) > 0 or len(b) > 0):
if( len(a) == 0 ):
newList.append(b[0])
b.pop(0)
elif( len(b) == 0 ):
newList.append(a[0])
a.pop(0)
elif( a[0] < b[0] ):
newList.append(a[0])
a.pop(0)
else:
newList.append(b[0])
b.pop(0)
return newList
>>> merge([3,4,8,9], [1,2,5,8])
Upvotes: 3
Reputation: 13158
Here's a version that uses the Python library heapq:
import heapq
def merge(aList, bList)
return list(heapq.merge(aList, bList))
Upvotes: 5