Manipulando listas com #Python. (#dev)

Manipulando listas com #Python. (#dev)

Overview

Olá, entusiastas da programação! Hoje, vamos mergulhar no mundo do Python para explorar algumas técnicas poderosas de manipulação e iteração de listas. Desde mesclar listas e acessar elementos de maneira criativa, até iterar com padrões específicos, este post está recheado de dicas úteis. Prepare seu ambiente de desenvolvimento e vamos codificar juntos!

Neste post, mostro um pouco das funcionalidades para acessar elementos, mesclar listas, mostrar listas no sentido inverso, iterar sobre a lista de 2 em 2 elementos, etc.

Primeiro, para todos os exemplos, vou usar as seguintes listas:

1foo = ["00 bacon", "01 foo", "02 bar", "03 lettuce", "04 pancakes", "05 waffles"]
2bar = [0, 1, 1, 2, 3, 5]

Mesclando listas

É possível mesclar listas da mesma forma que você passa *args para funções…

 1foobar = [*foo, *bar]
 2
 3
 4['00 bacon',
 5 '01 foo',
 6 '02 bar',
 7 '03 lettuce',
 8 '04 pancakes',
 9 '05 waffles',
10 0,
11 1,
12 1,
13 2,
14 3,
15 5]

Acessando o elemento n da lista

Este é o comportamento normal de qualquer lista/array que conhecemos. Não quis deixar o básico de fora…

1foo[0]
2
3'00 bacon'

Acessando o último elemento da lista

Sem funcionalidades como linq, geralmente você tem que pegar o tamanho da lista e subtrair 1 para saber o índice do último item da lista. No Python é só usar -1 como índice.

1foo[-1]
2
3'05 waffles'

Acessando o penúltimo elemento da lista

Esta lógica não é apenas para o último item. Você pode utilizar números negativos para percorrer a lista ao contrário (não é a melhor opção para isso, mas é uma das possibilidades).

1foo[-2]
2
3'04 pancakes'

Pulando n itens da lista

É possível utilizar as listas "pulando" ou ignorando os n primeiros itens dela.

1foo[1:]
2
3['01 foo', '02 bar', '03 lettuce', '04 pancakes', '05 waffles']

Pegando n itens da lista

De forma similar, você pode apenas pegar um número limitado de itens da lista, ao invés de pegar a lista toda de uma vez.

1foo[:3]
2
3['00 bacon', '01 foo', '02 bar']

Pegando uma "fatia" da lista

É possível combinar a lógica de "pular n itens" e "pegar n itens", mas essa abordagem tem um detalhe importante.

1foo[2:4] 
2
3['02 bar', '03 lettuce']

O detalhe aqui é o seguinte, primeiro você vai pegar os 4 primeiros itens e depois vai ignorar os 2 primeiros. É um pouco contraintuitivo de ler, já que o "comando" para pular os dois primeiros itens vem primeiro, mas a ideia é essa: Primeiro você separa os itens que vai utilizar, depois vc "aplica" o filtro de ignorar itens.

Neste caso, para o comando de "pegar n itens" você não precisa se preocupar com o tamanho da lista. O Python vai te devolver o número de itens que você pediu até chegar ao final da lista. Se ele não possuir a quantidade de elementos que você pediu, paciência. Seu resultado será uma lista menor. Veja este segundo exemplo:

1foo[2:940000]
2
3['02 bar', '03 lettuce', '04 pancakes', '05 waffles']

Veja que peguei os 940.000 itens e ignorei os 2 primeiros. Minha lista s;o tinha 6 elementos, então o meu resultado contempla apenas os 4 últimos elementos.

Iterando pela lista, 2 elementos por vez

Geralmente, quando fazemos um for em uma lista, ele passa por todos os elementos, mas você pode querer que ele passe por 1 e pule 1.

1foo[::2] 
2
3
4['00 bacon', '02 bar', '04 pancakes']

Sim, tem outro : no processo. Ele sempre existiu em todos os outros exemplos, mas quando ele é omitido, o padrão é 1.

Invertendo a lista

Você pode usar a abordagem anterior, combinada com os outros exemplos deste post para inverter a ordem da lista.

1foo[::-1]
2
3['05 waffles', '04 pancakes', '03 lettuce', '02 bar', '01 foo', '00 bacon']

Que tal inverter a lista, pegando um elemento e ignorando o outro?

1foo[::-2]
2
3['05 waffles', '03 lettuce', '01 foo']

Outra forma de inverter uma lista é utilizando a função reversed

1reversed(foo)
2
3
4<list_reverseiterator at 0x5cef000>

Porém ela retorna um generator e não a lista invertida. Utilizando este método, para pegar a lista invertida, você precisaria converte-la:

1list(reversed(foo)) 
2
3['05 waffles', '04 pancakes', '03 lettuce', '02 bar', '01 foo', '00 bacon']

Então, quando usar foo[::-1] e quando usar reversed(foo)? Bom, depende do que você precisar, do tamanho das listas, dos requerimentos de desempenho, etc.

Iterando por duas listas ao mesmo tempo

É possível fazer um for e passar por duas listas ao mesmo tempo.

 1for f, b in zip(foo, bar):
 2    print(f"This is an element of foo: {f}")
 3    print(f"This is an element of bar: {b}")
 4
 5
 6This is an element of foo: 00 bacon
 7This is an element of bar: 0
 8This is an element of foo: 01 foo
 9This is an element of bar: 1
10This is an element of foo: 02 bar
11This is an element of bar: 1
12This is an element of foo: 03 lettuce
13This is an element of bar: 2
14This is an element of foo: 04 pancakes
15This is an element of bar: 3
16This is an element of foo: 05 waffles
17This is an element of bar: 5

Se precisar, consegue também incluir um índice nesta operação:

 1for i, (f, b) in enumerate(zip(foo, bar)): 
 2    print(f"[{i}] This is an element of foo: {f}")
 3    print(f"[{i}] This is an element of bar: {b}")
 4
 5
 6[0] This is an element of foo: 00 bacon
 7[0] This is an element of bar: 0
 8[1] This is an element of foo: 01 foo
 9[1] This is an element of bar: 1
10[2] This is an element of foo: 02 bar
11[2] This is an element of bar: 1
12[3] This is an element of foo: 03 lettuce
13[3] This is an element of bar: 2
14[4] This is an element of foo: 04 pancakes
15[4] This is an element of bar: 3
16[5] This is an element of foo: 05 waffles
17[5] This is an element of bar: 5

Existe um detalhe importante! Se as listas forem de tamanhos diferentes, a iteração será feita pegando o número de elementos das menor lista.

 1bar2 = [42, *bar]
 2for i, (f, b) in enumerate(zip(foo, bar2)):  # Attention! if the lists have different sizes, will iterate the number of elements of the first list.
 3    print(f"[{i}] This is an element of foo: {f}")
 4    print(f"[{i}] This is an element of bar: {b}")
 5
 6print("Note that 5 (last element of bar2) was not included in the for")
 7
 8
 9[0] This is an element of foo: 00 bacon
10[0] This is an element of bar: 42
11[1] This is an element of foo: 01 foo
12[1] This is an element of bar: 0
13[2] This is an element of foo: 02 bar
14[2] This is an element of bar: 1
15[3] This is an element of foo: 03 lettuce
16[3] This is an element of bar: 1
17[4] This is an element of foo: 04 pancakes
18[4] This is an element of bar: 2
19[5] This is an element of foo: 05 waffles
20[5] This is an element of bar: 3
21Note that 5 (last element of bar2) was not included in the for

No exemplo acima, a lista foo tem um elemento a menos que a lista bar2 e isso fez com que o último elemento da lista bar2 fosse ignorado.

Realizando operações em cada item da lista

Uma forma rápida e limpa de multiplicarmos todos os elementos da lista bar por 2.

1x = [n*2 for n in bar] 
2print(bar)
3print(x)
4
5
6[0, 1, 1, 2, 3, 5]
7[0, 2, 2, 4, 6, 10]

Utilizando all e any

All e any são funções que não manipulam listas, mas são muito úteis e resolvi incluir aqui

1x = [n % 2 == 0 for n in bar]
2print(bar)
3print(x)
4print(f"All elements of bar are even numbers? - {all(x)}")
5print(f"Any elements of bar is an even number? - {any(x)}")

Acimn eu criar a lista x, que contem apenas true ou false, indicando se o elemento correspondente na lista bar é ou não par.

Quando chamo a função all, ela retorna true se todos os elementos de x forem true. De forma similar, any vai retornar true se pelo menos 1 item da lista x for true.

É isso. Espero ter ajudado!