The builtin zip() function is used  to combine the elements of 2 or more iterables index-wise.

data1 = [1, 2, 3]
data2 = 'ABC'

result = list(zip(data1, data2))
print(result)
for i in result:
     print(i)

When the involved iterables are of varying lengths, the function  simply combines the elements up to the length of the smallest iterable and drops the remaining elements.

data1 = [1, 2]
data2 = [10, 20, 30, 40]
for i in zip(data1, data2):
    print(i)

The zip_longest() function in itertools module  operates just like the builtin zip() function except that it combines the iterable's elements up to the longest length rather than the shortest. It allows us to specify a default  value for filling up missing elements in shorter iterables.

zip_longest(*iterables, fillvalue = None)
*iterables The arbitrary iterables to whose elements are to be combined.
fillvalue Specifies the value used to "pad" the shorter iterables to the same length as the longest one. It is set to None by default.

The function returns an iterator object which yields tuples where each one contains the elements from each iterable belonging to corresponding indices. The iterator stops when the longest iterable in the argument has been exhausted. Missing values in other iterables are replaced with fillvalue.   

from itertools import zip_longest

list1 = [1, 2] 
list2 = ['a', 'b', 'c', 'd'] 

zipped = zip_longest(list1, list2) 

print(list(zipped))

In the following example we specify a custom fill value.

from itertools import zip_longest

list1 = [1, 2] 
list2 = [10, 20, 30, 40] 
list3 = [100, 200, 300]

zipped = zip_longest(list1, list2, list3, fillvalue = -1) 

print(*zipped)