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!