In last week's snippet post we talked about the incredibly powerful zip function, and how we can use it to make our loops more Pythonic. This week we're going to be talking about the less well-known brother of zip: zip_longest.

zip_longest lives in the itertools module, which we've spoken about briefly before. itertools contains all kinds of useful functions revolving around iterative operations.

So how does zip_longest differ from plain old zip? Why should we care about it?

Well, when we use zip, zip will stop combining our iterables as soon as one of them runs out of elements. If the other iterables are longer, we just throw those excess items away. Take a look at this example:

l_1 = [1, 2, 3]
l_2 = [1, 2]

combinated = list(zip(l_1, l_2))

print(combinated)  # [(1, 1), (2, 2)]

As you can see, we just lost that 3 in l_1. That can sometimes be pretty problematic. We don't generally want to be throwing away data like this.

Luckily we have zip_longest here to save us.

Let's look at our example above again. This time using zip_longest.

from itertools import zip_longest

l_1 = [1, 2, 3]
l_2 = [1, 2]

combinated = list(zip_longest(l_1, l_2, fillvalue="_"))

print(combinated)  # [(1, 1), (2, 2), (3, '_')]

There are a few things to note here. For one, we got a third tuple in our zip object, meaning that the longer list was able to provide all of its values. Secondly, we have this keyword argument called fillvalue.

If we look at the print output for our little code segment, we can get some indication of what this does. As we can see, where there was no value to match to 3, zip_longest matched 3 to our fillvalue.

In essence, any time zip_longest doesn't have a value to match to one of our iterable's elements, it will place this fillvalue there to plug the gaps.

We can really use any fillvalue we want here: numbers, lists, dictionaries, None. Whatever you can think of. This makes it incredibly versatile, and it's definitely a good one to know about.

In case you're interested, we can call zip_longest without a fillvalue argument, in which case it will default to using None as a fillvalue.

Wrapping up

That's it for this snippet post! I hope you learnt something new, and I'm sure you'll find all sorts of awesome ways to use zip_longest in your own code.

As always, if you're serious about improving your Python, I'd recommend you take a look at our Complete Python Course! It has over 35 hours of material, along with quizzes, exercises, and several large projects, so it's an awesome way to develop your Python skills.

You should also think about signing up to our mailing list below, as we post regular coupon codes for our courses, ensuring that you always get the best deal.

Happy coding!