2
list_a = [1,7,9,35,36,37]
list_b = [3,4,5,40]

Expected output:

list_merged = [1,3,4,5,7,9,35,36,37,40]

Condition : must traverse both list only once

I know of zip which works as below and does quite fit in my requirement.

>>> x = [1, 2]
>>> y = [1, 3, 4, 5, 6]
>>> zip(x,y)
[(1, 1), (2, 3)]
>>> zip(y, x)
[(1, 1), (3, 2)]
naren
  • 49
  • 9
  • 1
    No, you do not need `zip` here. What have you tried? – Willem Van Onsem Nov 11 '17 at 09:44
  • i could find only zip examples, but that doesn't seem to work here. – naren Nov 11 '17 at 09:47
  • 3
    instead of searching some examples, can you first think of how you would solve the problem. How would you merge the two lists in order yourself? – Willem Van Onsem Nov 11 '17 at 09:48
  • Ideally i would go by each list, advance counter only from any one list, keep adding this poped element to third merged_list. continue until any of list gets exhausted and append all of remaining other list to merged_list. – naren Nov 11 '17 at 09:53
  • @naren That's exactly the way to go. Just try to implement that! – tobias_k Nov 11 '17 at 10:00
  • @tobias_k and Willem Thanks for you comments. just look at my answer what i tried, do you have anything different in your mind ? – naren Nov 11 '17 at 10:36
  • There is a deleted answer below by @sstyvane suggesting [`heapq.merge`](https://docs.python.org/3.6/library/heapq.html#heapq.merge) should be used - this answer is correct! It merges two (or more) sorted iterables in *linear* time. – Alex Riley Nov 11 '17 at 12:44

4 Answers4

1

Here is what i tried myself. solution is not really short but is simple one..

def linear_merge(list1, list2):
  i = 0
  j = 0
  list_m = [] # resultant list

  while i < len(list1) and j < len(list2):
    if list1[i] <= list2[j]: #take element from list 1 
      list_m.append(list1[i])
      i += 1
    else: # or take element from list 2
      list_m.append(list2[j])
      j += 1

  if i <= len(list1) - 1: #append remaing elements from list 1 
    list_m.extend(list1[i:])
  elif j <= len(list2) - 1: #or append remaing elements from list 2
    list_m.extend(list2[j:])

  return list_m

This works at first hand, to me, seems the C way. Any more pythonic solution ?

naren
  • 49
  • 9
0

You can traverse the two list with different index variables.

list_a = [1,7,9,35,36,37]
list_b = [3,4,5,40]
index_a = 0
index_b = 0
merged = []
while index_a<len(list_b) or index_b < len(list_b):
    if index_a<len(list_a) and list_a[index_a]<=list_b[index_b]:
        merged.append(list_a[index_a])
        index_a +=1
    elif index_b<len(list_b):
        merged.append(list_b[index_b])
        index_b +=1
print merged
# [1, 3, 4, 5, 7, 9, 35, 36, 37, 40]
Mitiku
  • 5,337
  • 3
  • 18
  • 35
  • 1
    This fails (infinite loop) if `list_a` is shorter than `list_b`, e.g. `list_a = [1,7,9]`. Better check whether _both_ indices are smaller than the length and then `extend` with whatever is left after the loop. – tobias_k Nov 11 '17 at 09:54
0

The methodology is:

Keep two pointers(for the index of the lists) for each list and check the smaller element. When the smaller element is found move pointer next element for that list. Keep another(second list) pointer as it is. So you can traverse just one time for each list. If you implement above methodology, only thing you miss is that the biggest(last) element. So one more pointer is used to keep the last element.

Hope this helps:

list_a = [1,7,9,35,36,37] # also works for list_a = [1,7,9,35,36,45]
list_b = [3,4,5,40]

ptr_a = 0 # pointer for a
ptr_b = 0 # pointer for b
last = 0 # pointer for last element
list_merged = [] # merged result list

while ptr_a<len(list_a) and ptr_b<len(list_b):
    if list_a[ptr_a] < list_b[ptr_b]:
        list_merged.append(list_a[ptr_a])
        ptr_a = ptr_a + 1
        last = list_b[ptr_b] # assign last element

    else:
        list_merged.append(list_b[ptr_b])
        ptr_b = ptr_b + 1
        last = list_a[ptr_a] # assign last element

# at the end of the while loop the last element of 
# the 'merged list' has not added. Below line is to add it.
list_merged.append(last)
print list_merged
Ersel Er
  • 731
  • 6
  • 22
0

The easiest way to merge two lists is to use the '+' operator for the two


This is more of a pythonic way than the algorithmic way.

list1 = [1,2,3]
list2 = [4,5,6]

list3 = list1+list2 

#This merges both lists and puts them in list3

If you want a more algorithmic approach ....

use the below code :-

list3 = [ ]
for i in list1:
   list3.append(i);
for i in list2:
   list3.append(i) ;

Now list3 will have the merged result.

How ever I should warn you that , the first pythonic way is almost 3 times faster than the second way. (just tested it with timeit module)

Natesh bhat
  • 12,274
  • 10
  • 84
  • 125