Através das funções nativas zip e zip_longest podemos encontrar uma forma fácil e prática de unir iteráveis

Veja:

cidades = ['São Paulo', 'Curitiba', 'Rio de Janeiro', 'Brasília']
estados = ['SP', 'PR', 'RJ', 'DF']

cidades_estados = zip(cidades, estados)

Ao executarmos a função zip criamos um iterador, que pode ser iterado usando a função next ou até percorrido em um for

>>>for endereco in cidades_estados:
>>>...   print(endereco)
>>>...
('São Paulo', 'SP')
('Curitiba', 'PR')
('Rio de Janeiro', 'RJ')
('Brasília', 'DF')

<aside> <img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9160bcfe-ddb1-4c60-a457-ff30fc08750d/IMG_4045.png" alt="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9160bcfe-ddb1-4c60-a457-ff30fc08750d/IMG_4045.png" width="40px" /> Se os iteráveis tiverem tamanhos diferentes, a função zip criará um iterador com o tamanho do menor iterável.

</aside>

Veja um exemplo:

>>>cardinal = ['um', 'dois', 'tres']
>>>numero = [1, 2, 3, 4, 5] # esse iterável é maior
>>>list(zip(numero, cardinal) # convertemos o zip em uma lista
[(1, 'um'), (2, 'dois'), (3, 'tres')]

Se quisermos que o iterador tenha o tamanho do maior iterável usamos a função zip_longest da biblioteca padrão itertools. A função preencherá os valores restantes com None


>>>from itertools import zip_longest
>>>cardinal = ['um', 'dois', 'tres']
>>>numero = [1, 2, 3, 4, 5]
>>>list(zip_longest(numero, cardinal)
[(1, 'um'), (2, 'dois'), (3, 'tres'), (4, None), (5, None)]

Se quisermos preencher os valores restantes com um valor padrão, usamos o argumento fillvalue

>>>list(zip_longest(numero, cardinal, fillvalue='algum cardinal')
[(1, 'um'), (2, 'dois'), (3, 'tres'), (4, 'algum cardinal'), (5, 'algum cardinal')]