Na programação Python, a compreensão e o uso eficaz de iteráveis são fundamentais para a codificação proficiente. Iteráveis são objetos que você pode iterar ou fazer um loop. Eles suportam a passagem sequencial de elementos dentro deles, o que os torna uma ferramenta essencial para acessar e manipular elementos em objetos ou estruturas de dados.

Este artigo explora como usar corretamente os iteráveis do Python, concentrando-se nos tipos de dados iteráveis integrados da linguagem: listas, tuplas, dicionários, strings de caracteres e conjuntos. Ele também explica como implementar tipos iteráveis personalizados e realizar operações avançadas.

Como fazer um loop através de iteráveis em Python

Em Python, você pode iterar através de diversos tipos de iteráveis usando um loop for. Isso permite que você navegue por sequências e realize operações em itens individuais dentro de listas, conjuntos e dicionários.

A palavra-chave for em Python é diferente de sua utilidade em outras linguagens orientadas a objetos, como Java. Os loops do Python for funcionam mais como métodos de iterador. Aqui estão exemplos para demonstrar o loop em iteráveis:

1. Looping em uma lista

As listas são coleções ordenadas de itens, o que permite a iteração fácil usando um loop for.

fruits_list = ["Apple", "Mango", "Peach", "Orange", "Banana"]

for fruit in fruits_list:
    print(fruit)

No código acima, fruit atua como um iterador que o loop usa para percorrer cada elemento da lista e, ao mesmo tempo, imprimi-los. O loop é encerrado após a avaliação do último elemento da lista. O código acima deve gerar o seguinte resultado:

Apple
Mango
Peach
Orange
Banana

2. Iteração em uma tupla

As tuplas são semelhantes às listas, mas são imutáveis. Você pode iterar por elas da mesma forma que as listas.

fruits_tuple = ("Apple", "Mango", "Peach", "Orange", "Banana")

for fruit in fruits_tuple:
	print(fruit)

Neste exemplo, o loop for itera pela tupla e, em cada iteração, a variável fruit assume o valor do elemento atual na tupla. O código deve fornecer o seguinte resultado:

Apple
Mango
Peach
Orange
Banana

3. Looping em conjuntos

Os conjuntos são coleções não ordenadas de elementos exclusivos. Você pode percorrê-los usando um loop for.

fruits_set = {"Apple", "Mango", "Peach", "Orange", "Banana"}

for fruit in fruits_set:
	print(fruit)

Neste exemplo, o loop for itera pelo conjunto. Entretanto, como os conjuntos não são ordenados, a ordem de iteração pode não ser a mesma que a ordem em que os elementos foram definidos no conjunto. Em cada iteração, a variável fruit assume o valor do elemento atual no conjunto. O código deve gerar um resultado semelhante ao seguinte (a ordem pode variar):

Mango
Banana
Peach
Apple
Orange

4. Iteração através de strings

As strings de caracteres são sequências de caracteres que você pode percorrer caractere por caractere.

string = "Kinsta"

for char in string:
	print(char)

O código acima itera pela string de caracteres “Kinsta” e imprime cada caractere em uma nova linha. Em cada iteração, a variável char assume o valor do caractere atual na string de caracteres. O código deve gerar o seguinte resultado:

K
i
n
s
t
a

5. Percorrendo um dicionário

O uso do loop for é semelhante para listas, conjuntos, tuplas e strings de caracteres, mas é diferente para dicionários, pois eles usam pares de valores-chave para armazenar itens. Os dicionários apresentam um caso único de looping, pois você pode iterá-los usando diferentes abordagens. Aqui estão as diferentes abordagens que você pode usar para percorrer um dicionário Python:

  • Iteração por chaves:
    countries_capital = {
        "USA": "Washington D.C.",
        "Australia": "Canberra",
        "France": "Paris",
        "Egypt": "Cairo",
        "Japan": "Tokyo"
    }
    
    for country in countries_capital.keys():
        print(country)

    O código acima define um dicionário chamado countries_capital, em que os nomes dos países são as chaves e suas respectivas capitais são os valores. O loop for itera pelas chaves do dicionário countries_capital usando o método keys(). Esse método retorna um objeto de visualização que exibe uma lista das chaves do dicionário, o que facilita o loop de todas as chaves. Em cada iteração, a variável country assume o valor da chave atual. Esse código deve gerar o seguinte resultado:

    USA
    Australia
    France
    Egypt
    Japan
  • Iterando pelos valores:
    countries_capital = {
        "USA": "Washington D.C.",
        "Australia": "Canberra",
        "France": "Paris",
        "Egypt": "Cairo",
        "Japan": "Tokyo"
    }
    
    for capital in countries_capital.values():
        print(capital)

    No código acima, o for faz a iteração dos valores do dicionário countries_capital usando o método values(). Esse método retorna um objeto de visualização que exibe uma lista dos valores no dicionário, facilitando o loop de todos os valores. Em cada iteração, a variável capital assume o valor do valor atual na lista. Esse código deve gerar o seguinte resultado:

    Washington D.C.
    Canberra
    Paris
    Cairo
    Tokyo
  • Iterando por pares de valores-chave:
    countries_capital = {
        "USA": "Washington D.C.",
        "Australia": "Canberra",
        "France": "Paris",
        "Egypt": "Cairo",
        "Japan": "Tokyo"
    }
    
    for country, capital in countries_capital.items():
        print(country, ":", capital)

    O código acima demonstra como você pode iterar pelas chaves e pelos valores do dicionário countries_capital usando o método items(). O método items() retorna um objeto de visualização que exibe uma lista de tuplas de valores-chave no dicionário. No loop for, cada iteração descompacta um par chave-valor do elemento atual da lista. As variáveis country e capital recebem a chave e o valor correspondentes, respectivamente. Esse código deve gerar o seguinte resultado:

    USA : Washington D.C.
    Australia : Canberra
    France : Paris
    Egypt : Cairo
    Japan : Tokyo

Iteração avançada com enumerate() em Python

Outra maneira de iterar sobre os iteráveis Python enquanto você retorna o índice e o valor correspondente dos elementos é por meio da função enumerate(). Dê uma olhada neste exemplo:

fruits_list = ["Apple", "Mango", "Peach", "Orange", "Banana"]

for index, fruit in enumerate(fruits_list):
    print(fruit, index)

Aqui está o resultado:

Apple 0
Mango 1
Peach 2
Orange 3
Banana 4

A função enumerate também permite que você especifique o índice inicial, além de 0, para a operação de iteração. Você pode modificar o exemplo acima da seguinte forma:

fruits_list = ["Apple", "Mango", "Peach", "Orange", "Banana"]
for index, fruit in enumerate(fruits_list, start = 2):
    print(fruit, index)

Aqui está o resultado:

Apple 2
Mango 3
Peach 4
Orange 5
Banana 6

Observe que, embora esse exemplo especifique o índice inicial da enumeração, o enumerate não aplica uma indexação baseada em zero ao iterável, como é o caso das listas nativas. Ele simplesmente acrescenta o valor inicial ao primeiro elemento da lista até o último.

Como implementar geradores Python

Geradores são iteráveis especiais em Python que permitem a você construir objetos geradores sem criar explicitamente tipos integrados como listas, conjuntos ou dicionários. Você pode usar geradores para produzir valores à medida que avança, com base na lógica de geração.

Os geradores usam a instrução yield para retornar os valores gerados um de cada vez. Aqui está um exemplo de iteráveis de gerador:

def even_generator(n):
    counter = 0
    while counter <= n:
        if counter % 2 == 0:
            yield counter
        counter += 1

for num in even_generator(20):
    print(num)

O código fornecido define uma função even_generator que produz uma sequência de números pares de 0 a um n especificado usando a instrução yield. Ele utiliza um loop para gerar esses valores e itera o resultado usando o iterador num, garantindo a avaliação de todos os valores dentro do intervalo fornecido. Esse código gera uma lista de números pares de 0 a 20, conforme mostrado abaixo:

0
2
4
6
8
10
12
14
16
18
20

Você pode obter ainda mais concisão ao trabalhar com expressões de gerador. Por exemplo, você pode criar uma função geradora que também incorpora a lógica de loop:

cube = (num ** 3 for num in range(1, 6))
for c in cube:
    print(c)

Aqui, você atribui a variável cube ao resultado de uma função que calcula o cubo de valores no intervalo de 1 a 6. Em seguida, você percorre os valores dentro do intervalo especificado, gerando o resultado do cálculo, um após o outro. O resultado é o seguinte:

1
8
27
64
125

Como criar iteráveis personalizados

O Python permite que você personalize ainda mais as operações de iteráveis usando iteradores. Os objetos de iterador implementam o protocolo de iterador e contêm dois métodos: __iter__() e __next__(). O método __iter__() retorna um objeto iterador, enquanto __next__() retorna o próximo valor em um contêiner iterável. Aqui está um exemplo de iteradores em Python:

even_list = [2, 4, 6, 8, 10]
my_iterator = iter(even_list)
print(next(my_iterator)) # Prints 2
print(next(my_iterator)) # Prints 4
print(next(my_iterator)) # Prints 6

Neste exemplo, você usa o método iter() para criar um objeto iterador (my_iterator) a partir da lista. Para acessar cada um dos elementos da lista, você envolve o objeto iterador com o método next(). Como as listas são coleções ordenadas, o iterador retorna os elementos sequencialmente.

Os iteradores personalizados são ideais para operações que envolvem grandes conjuntos de dados que você não pode carregar na memória simultaneamente. Como a memória é cara e sujeita a restrições de espaço, você pode usar um iterador para processar elementos de dados individualmente sem carregar todo o conjunto de dados na memória.

Funções iteráveis

O Python usa funções para percorrer, manipular e inspecionar os elementos da lista. Algumas funções de lista comuns incluem:

  • sum – Retorna a soma de um determinado iterável, desde que a coleção seja de tipos numéricos (inteiros, valores de ponto flutuante e números complexos)
  • any – Retorna true se algum dos elementos iteráveis for verdadeiro. Caso contrário, ele retornará false.
  • all – Retorna true se todos os elementos iteráveis forem verdadeiros. Caso contrário, retorna false.
  • max – Retorna o valor máximo de uma determinada coleção iterável
  • min – Retorna o valor mínimo de uma determinada coleção iterável
  • len – Retorna o comprimento de um determinado iterável
  • append – Adiciona um valor ao final de uma lista iterável

O exemplo abaixo demonstra essas funções com uma lista:

even_list = [2, 4, 6, 8, 10]

print(sum(even_list))
print(any(even_list))
print(max(even_list))
print(min(even_list))
even_list.append(14) # Add 14 to the end of the list
print(even_list)
even_list.insert(0, 0) # Insert 0 and specified index [0]
print(even_list)
print(all(even_list)) # Return true only if ALL elements in the list are true
print(len(even_list)) # Print the size of the list

Aqui está o resultado:

30
True
10
2
[2, 4, 6, 8, 10, 14]
[0, 2, 4, 6, 8, 10, 14]
False
7

No exemplo acima, a função append adiciona um único parâmetro (14) ao final da lista. A função insert permite que você especifique o índice para inserção. Portanto, even_list.insert(0, 0) insere 0 no índice [0].
A instrução print(all(even_list)) retorna false porque há um valor 0 na lista, interpretado como false. Por fim, print(len(even_list)) gera o comprimento do iterável.

Operações avançadas de iteráveis

O Python oferece recursos avançados que promovem a concisão nas operações com iteráveis. A seguir, você encontrará alguns deles.

1. Compreensões de lista

As compreensões de lista permitem que você crie novas listas aplicando uma função a cada elemento das listas existentes. Aqui está um exemplo:

my_numbers = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
even_number_list = [num for num in my_numbers if num%2 == 0]
print(even_number_list)

Neste trecho de código, uma lista chamada my_numbers é criada com números inteiros de 11 a 20. O objetivo é gerar uma nova lista, even_number_list, contendo apenas números inteiros pares. Para isso, aplique uma compreensão de lista que retorne um número inteiro de my_numbers somente se esse número inteiro for par. A instrução if contém a lógica que retorna os números pares.

Aqui está o resultado:

[12, 14, 16, 18, 20]

2. Zip

A função zip() do Python combina vários iteráveis em tuplas. As tuplas armazenam vários valores em uma variável e são imutáveis. Veja como você pode combinar iteráveis usando zip():

fruits = ["apple", "orange", "banana"]
rating = [1, 2, 3]

fruits_rating = zip(rating, fruits)
print(list(fruits_rating))

Neste exemplo, fruits_rating emparelha cada classificação com uma fruta, criando um único iterável. O resultado é:

[(1, 'apple'), (2, 'orange'), (3, 'banana')]

Esse código funciona como um sistema de classificação para diferentes frutas, com a primeira lista (fruits) representando as frutas e a segunda lista representando as classificações em uma escala de 1 a 3.

3. Filtro

Outra função avançada, filter, recebe dois argumentos: uma função e um iterável. Ela aplica a função a cada elemento do iterável e, em seguida, retorna um novo iterável contendo somente os elementos para os quais a função retorna um valor true. O exemplo a seguir filtra uma lista de valores inteiros em um determinado intervalo para que você retorne apenas os valores pares:

def is_even(n):
    return n%2 == 0

nums_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_list = filter(is_even, nums_list)
print(list(even_list))

No código acima, você começa definindo uma função, is_even, para computar um número par passado a ela. Em seguida, você cria uma lista de valores inteiros entre 1 e 10 – nums_list. Por fim, você define uma nova lista, even_list, que usa a função filter() para aplicar o método definido pelo usuário à lista original e retornar somente os elementos pares da lista. Aqui está o resultado:

[2, 4, 6, 8, 10]

4. Mapa

Assim como a função filter(), a função map() do Python recebe um iterável e uma função como argumentos. Mas, em vez de retornar elementos do iterável inicial, ela retorna um novo iterável que contém o resultado da função aplicada a cada elemento do primeiro iterável. Para elevar uma lista de inteiros ao quadrado, use a função map():

my_list = [2, 4, 6, 8, 10]
square_numbers = map(lambda x: x ** 2, my_list)
print(list(square_numbers))

Nesse código, x é o iterador que percorre a lista e a transforma por meio do cálculo do quadrado. A função map() executa essa operação tomando a lista original como argumento junto com uma função de mapeamento. O resultado é o seguinte:

[4, 16, 36, 64, 100]

5. Sorted

A função sorted classifica os elementos de um determinado iterável em uma ordem específica (crescente ou decrescente) e os retorna como uma lista. Ela aceita apenas 3 parâmetros: iterable, reverse(opcional) e key(opcional). Em seguida, reverse tem como padrão False e, se definido como True, os itens são classificados em ordem decrescente. key é uma função que calcula um valor para determinar a ordem de classificação do elemento em um iterável e tem como padrão None.

Aqui está um exemplo de como você pode aplicar a função sorted em vários iteráveis:

# set
py_set = {'e', 'a', 'u', 'o', 'i'}
print(sorted(py_set, reverse=True))

# dictionary
py_dict = {'e': 1, 'a': 2, 'u': 3, 'o': 4, 'i': 5}
print(sorted(py_dict, reverse=True))

# frozen set
frozen_set = frozenset(('e', 'a', 'u', 'o', 'i'))
print(sorted(frozen_set, reverse=True))

# string
string = "kinsta"
print(sorted(string))

# list
py_list = ['a', 'e', 'i', 'o', 'u']
print(py_list)

Isso dá a você o seguinte resultado:

['u', 'o', 'i', 'e', 'a']
['u', 'o', 'i', 'e', 'a']
['u', 'o', 'i', 'e', 'a']
['a', 'i', 'k', 'n', 's', 't']
['a', 'e', 'i', 'o', 'u']

Como lidar com casos extremos e erros em iteráveis

Os casos extremos são comuns em muitos cenários de programação, e você deve antecipá-los em iteráveis. Vamos explorar algumas possibilidades que você pode encontrar.

1. Iteráveis vazios

Você pode se deparar com problemas quando um iterável está vazio, mas alguma lógica de programação tenta percorrê-lo. Você pode abordar isso programaticamente para evitar ineficiências. Aqui está um exemplo usando uma declaração if not para verificar se uma lista está vazia:

fruits_list=[]
if not fruits_list:
    print("The list is empty")

Este é o resultado:

The list is empty

2. Iteráveis aninhados

O Python também oferece suporte a iteráveis aninhados, que são objetos iteráveis que contêm outros iteráveis dentro deles. Por exemplo, você pode ter uma lista de alimentos contendo listas aninhadas de categorias de alimentos, como carnes, vegetais e grãos. Veja como você pode modelar esse cenário usando iteráveis aninhados:

food_list = [["kale", "broccoli", "ginger"], ["beef", "chicken", "tuna"], ["barley", "oats", "corn"]]
for inner_list in food_list:
    for food in inner_list:
        print(food)

No código acima, a variável food_list contém três listas aninhadas, representando diferentes categorias de alimentos. O loop externo (for inner_list in food_list:) percorre a lista primária e o loop interno (for food in inner_list:) percorre cada lista aninhada, imprimindo cada item alimentar. O resultado é o seguinte:

kale
broccoli
ginger
beef
chicken
tuna
barley
oats
corn

3. Tratamento de exceções

Em Python, os iteráveis também suportam operações de tratamento de exceções. Por exemplo, você pode iterar em uma lista e encontrar um erro IndexError. Esse erro significa que você está tentando fazer referência a um elemento que excede os limites do iterável. Veja como você pode tratar essa exceção usando um bloco try-except:

fruits_list = ["apple", "mango", "orange", "pear"]
try:
    print(fruits_list[5])
except IndexError:
    print("The index specified is out of range.")

No código acima, o iterável fruits_list contém cinco elementos mapeados pelos índices de 0 a 5 na coleção de listas. A frase try contém uma função print que tenta exibir o valor no índice 5 do iterável, que não existe. Isso executa a função except clause, returning the associated error message. The console returns the error:

The index specified is out of range.

Resumo

Dominar a iteração em Python é fundamental para que você tenha um código eficiente e legível. Compreender as várias maneiras de iterar sobre diferentes estruturas de dados, usando compreensões, geradores e aproveitando as funções integradas torna você um programador Python proficiente.

Seja trabalhando com listas, dicionários, strings de caracteres ou objetos personalizados, saber como usar e manipular iteráveis é uma habilidade indispensável na programação em Python.

Quando você terminar de criar seu aplicativo Python e quiser hospedá-lo on-line, experimente a hospedagem de aplicativos da Kinsta. Seus primeiros US$ 20 são por nossa conta!

Você sentiu falta de alguma coisa neste artigo? Por favor, compartilhe na seção de comentários abaixo!

Jeremy Holcombe Kinsta

Editor de Conteúdo & Marketing na Kinsta, Desenvolvedor Web WordPress e Escritor de Conteúdo. Fora do universo WordPress, eu curto praia, golfe e filmes. Também enfrento problemas de gente alta ;).