pythonlistpython-2.7python-itertools

Using zip_longest on unequal lists but repeat the last entry instead of returning None


There is an existing thread about this Zipping unequal lists in python in to a list which does not drop any element from longer list being zipped

But it's not quite I'm after. Instead of returning None, I need it to copy the previous entry on the list.

Is this possible?

a = ["bottle","water","sky"]
b = ["red", "blue"]
for i in itertools.izip_longest(a,b):
    print i

#result
# ('bottle', 'red')
# ('water', 'blue')
# ('sky', None) 

# What I want on the third line is
# ('sky', 'blue')

Solution

  • itertools.izip_longest takes an optional fillvalue argument that provides the value that is used after the shorter list has been exhausted. fillvalue defaults to None, giving the behaviour you show in your question, but you can specify a different value to get the behaviour you want:

        fill = a[-1] if (len(a) < len(b)) else b[-1]
        for i in itertools.izip_longest(a, b, fillvalue=fill):
            print i
    

    (Obviously if the same list is always the shorter one then choosing the fill character is even easier.)