Ci

Ciclos em Julia

2 exercícios

Sobre Ciclos

Existem basicamente dois tipos de ciclos:

  1. Repetir até que uma condição seja satisfeita.
  2. Percorrer os elementos de uma coleção.

Ambos são possíveis em Julia, embora o segundo possa ser mais comum.

O ciclo while

Para problemas em aberto, em que o número de voltas ao ciclo é desconhecido à partida, Julia tem o ciclo while.

A forma básica é bastante simples:

while condition
    do_something()
end

Neste caso, o programa continua a dar voltas ao ciclo até que condition deixe de ser true.

Há duas formas de sair do ciclo antecipadamente:

  • Um break faz o ciclo terminar, e a execução continua na linha seguinte ao end do ciclo.
  • Um return x interrompe a execução da função atual e devolve o valor x a quem a chamou.

Com estas opções disponíveis, por vezes pode ser prático criar um ciclo "infinito" com while true ... end e depois contar com a descoberta de uma condição de paragem dentro do corpo do ciclo para acionar um break ou um return.

Percorrer uma coleção

O exemplo mais simples é percorrer um intervalo.

Se quisermos fazer algo 10 vezes:

for n in 1:10
    do_something(n)
end

Se a iteração atual não cumprir alguma condição, é possível saltar imediatamente para a iteração seguinte com um continue:

for n in 1:10
    if is_useless(n)
        continue
    end
    
    # we decided this iteration could be useful
    do_something_slow(n)
end

Numa forma mais curta, o bloco if pode ser substituído por is_useless(n) && continue.

Podes percorrer muitos outros tipos de coleções: elementos de um array, carateres de uma string, chaves de um dicionário...

O requisito é que a coleção seja iterable. Isto será explicado com mais detalhe num Conceito mais adiante, mas, em essência, a coleção tem de ter uma forma de fornecer o item seguinte quando lhe é pedido, além de uma forma de indicar que chegou ao fim e que já não há mais itens.

Os exemplos até aqui percorrem o intervalo 1:10, em que o valor é também o índice do ciclo.

De um modo mais geral, pode ser preciso o índice, e não apenas o valor. Para isso, usa-se a função eachindex(), por exemplo for i in eachindex(my_array) ... end.

Compreensões

Escrever ciclos explícitos tende a ser menos comum em Julia do que em muitas linguagens tradicionais, porque há várias opções mais concisas.

Uma situação especialmente comum é quando precisamos de construir um novo vetor a partir dos elementos de outra coleção (vetor, string, conjunto... há muitas possibilidades).

Quem gosta de compreensões de listas em Python vai ficar satisfeito por saber que Julia pode usar uma sintaxe semelhante.

A essência disto é criar um ciclo muito compacto dentro de um vetor.

A sintaxe mais simples tem a forma result = [f(x) for x in some_collection].

Com um ciclo tradicional, isso poderia escrever-se assim:

result = []
for x in some_collection
    push!(result, f(x))
end

Opcionalmente, pode acrescentar-se uma condicional no fim, para selecionar apenas os elementos correspondentes da coleção:

# multiples of 3
julia> [n^2 for n in 1:10 if n%3 == 0]
3-element Vector{Int64}:
  9
 36
 81

# letters beyond 'h' in the alphabet
julia> [uppercase(c) for c in "Julia" if c > 'h']
3-element Vector{Char}:
 'U': ASCII/Unicode U+0055 (category Lu: Letter, uppercase)
 'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)
 'I': ASCII/Unicode U+0049 (category Lu: Letter, uppercase)

A sintaxe é semelhante à de Python, mas não é idêntica. Há algumas divergências no caso de múltiplas variáveis e/ou arrays multidimensionais, por isso este tópico será abordado com mais detalhe num Conceito mais adiante.

Outras opções

Enquanto linguagem moderna e maioritariamente funcional, Julia tem (como não podia deixar de ser) várias formas de trabalhar com coleções, e não apenas um ciclo explícito ou um ciclo compactado numa compreensão.

Conceitos mais adiante vão abordar alternativas como broadcasting e funções de ordem superior.

Editar via GitHub A ligação abre numa nova janela ou separador

Aprende Ciclos