Home > Software design >  Adding individual items from two lists into a new list
Adding individual items from two lists into a new list

Time:10-22

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]))
    []
    
  • Related