Write a function that expects two lists of integers, a and b, as parameters and returns a list. The function should merge the elements of both input lists by index and return them as tuples in a new list. If one list is shorter than the other, the last element of the shorter list should be repeated as often as necessary. If one or both lists are empty, the empty list should be returned.
Please consider the following examples:
merge([0, 1, 2], [5, 6, 7]) # should return [(0, 5), (1, 6), (2, 7)]
merge([2, 1, 0], [5, 6]) # should return [(2, 5), (1, 6), (0, 6)]
merge([], [2, 3]) # should return []
You can assume that the parameters are always valid lists and you do not need to provide any kind of input validation.
My attempt:
def merge(a, b):
if len(a) == 0 or len(b) == 0:
mergelist = []
elif len(a) > len(b):
for i in range(0, len(b)):
mergelist = [a[i], b[i]]
for i in range(len(b), len(a)):
mergelist = [a[i], b[len(b)]]
elif len(b) > len(a):
for i in range(0, len(a)):
mergelist = [a[i], b[i]]
for i in range(len(a), len(b)):
mergelist = [a[len(a)], b[i]]
return mergelist
print(merge([0, 1, 2], [5, 6]))
Can someone tell me why my code is wrong? My IDE says
the list index is out of range
but i checked it over and over, it isn't,,,i think.
CodePudding user response:
There are a few things to update in your code:
(1) change this format mergelist = [a[i], b[i]]
to this format mergelist.append((a[i], b[i]))
(2) need to take care of the case when len(a) == len(b)
(3) list index is out of range because list index starts with zero. For example if len(a) is 2, the allowed index in range would be 0 and 1 only. So 2 is out of range.
Try this code:
def merge(a, b):
mergelist = []
if len(a) == 0 or len(b) == 0:
return mergelist
elif len(a) >= len(b): #takes care of len(a)==len(b)
for i in range(0, len(b)):
mergelist.append((a[i], b[i]))
for i in range(len(b), len(a)):
mergelist.append((a[i], b[len(b)-1])) #index minus 1
elif len(b) > len(a):
for i in range(0, len(a)):
mergelist.append((a[i], b[i]))
for i in range(len(a), len(b)):
mergelist.append((a[len(a)-1], b[i])) #index minus 1
return mergelist
print(merge([0, 1, 2], [5, 6]))
print(merge([5, 6], [0, 1, 2]))
print(merge([0, 1, 2], [5, 6, 7])) # should return [(0, 5), (1, 6), (2, 7)]
print(merge([2, 1, 0], [5, 6])) # should return [(2, 5), (1, 6), (0, 6)]
print(merge([], [2, 3])) # should return []
Output:
[(0, 5), (1, 6), (2, 6)]
[(5, 0), (6, 1), (6, 2)]
[(0, 5), (1, 6), (2, 7)]
[(2, 5), (1, 6), (0, 6)]
[]
CodePudding user response:
you can use zip()
for solving this problem
def merge(a,b):
zipped = list(zip(a,b))
if a and b:
if len(a) == len(b):
return zipped
else:
zipped.append((a[-1],b[-1]))
return zipped
else:
return []
print(merge([0, 1, 2], [5, 6]))
print(merge([5, 6], [0, 1, 2]))
print(merge([0, 1, 2], [5, 6, 7])) # should return [(0, 5), (1, 6), (2, 7)]
print(merge([2, 1, 0], [5, 6])) # should return [(2, 5), (1, 6), (0, 6)]
print(merge([], [2, 3])) # should return []
#output:
# [(0, 5), (1, 6), (2, 6)]
# [(5, 0), (6, 1), (6, 2)]
# [(0, 5), (1, 6), (2, 7)]
# [(2, 5), (1, 6), (0, 6)]
# []
but this function won't work if some of lists is longer than the other one by 2 or more items
CodePudding user response:
A shorter variant that does the same:
def merge(a,b):
if len(a) == 0 or len(b) == 0:
return []
elif len(a) >= len(b):
b = b [b[-1]]*(len(a)-len(b))
else:
a = a [a[-1]]*(len(b)-len(a))
return list(zip(a,b))
print(merge([0, 1, 2], [5, 6]))
print(merge([5, 6], [0, 1, 2]))
print(merge([0, 1, 2], [5, 6, 7]))
print(merge([2, 1, 0], [5, 6]))
print(merge([], [2, 3]))
output:
[(0, 5), (1, 6), (2, 6)]
[(5, 0), (6, 1), (6, 2)]
[(0, 5), (1, 6), (2, 7)]
[(2, 5), (1, 6), (0, 6)]
[]
CodePudding user response:
How about
def merge(a,b):
if len(a) == len(b) or not a or not b: return [ (x, y) for x, y in zip(a, b) ]
return [ (x, y) for x, y in zip(a [a[-1]] * (len(b) - len(a)), b) ] if len(a) < len(b) else [ (x, y) for x, y in zip(a, b [b[-1]] * (len(a) - len(b))) ]
Or
def merge(a,b):
if len(a) == len(b) or not a or not b: return [ (x, y) for x, y in zip(a, b) ]
[a, b] = [a, b] if len(a) < len(b) else [b, a]
return [ (x, y) for x, y in zip(a [a[-1]] * (len(b) - len(a)), b)]
Demo
>>> print(merge([0, 1, 2], [5, 6, 7])) # should return [(0, 5), (1, 6), (2, 7)] [(0, 5), (1, 6), (2, 7)] >>> print(merge([2, 1, 0], [5, 6])) # should return [(2, 5), (1, 6), (0, 6)] [(2, 5), (1, 6), (0, 6)] >>> print(merge([], [2, 3])) []