TransWikia.com

Não consegui entender bem como esse código funciona

Stack Overflow em Português Asked by Yasmin Teixeira on September 26, 2021

Vi esse código para fazer a transposição da matriz mas não consegui entender bem como ele funciona.

Pra mim esse row[i] parece mais como um "marcador" de um índice, por exemplo, linha 1, linha 2, linha 3 e linha 4. Não entendi bem como ele funciona.

Além disso o range(2) também me confunde porque pra mim range era usado para um intervalo de números.

Alguém consegue me explicar?

matrix = [[1, 2],[3,4],[5,6],[7,8]]
transpose = [[row[i] for row in matrix] for i in range(2)]
print(transpose)

One Answer

Se for assim, fica mais fácil de entender?

matrix = [[1, 2], [3, 4], [5, 6], [7, 8]]
transpose = []
for i in range(2):
    linha = []
    for row in matrix:
        linha.append(row[i])

    transpose.append(linha)

Isso é equivalente ao que a list comprehension está fazendo.


Além disso o range(2) também me confunde porque pra mim range era usado para um intervalo de números.

Sim, range serve para isso mesmo, o que muda é o que você faz com esses números.

De forma geral, range(n) representa o intervalo entre zero e n - 1 (o n não é incluso no range). Então range(2) representa o intervalo entre zero e 1 (ou seja, apenas os números 0 e 1).

Então o for i in range(2) está servindo para percorrer os números 0 e 1, e depois, para cada "linha" da matriz, pega-se o elemento que está na posição i. Em outras palavras:

  • na primeira iteração, i vale zero.
  • cada elemento de matrix é uma lista (o primeiro elemento é a lista [1, 2], o segundo é a lista [3, 4], etc). O for row in matrix percorre essas listas
    • dentro do for row in matrix, pega-se o primeiro elemento de cada lista (row[i], e como i vale zero, pega-se o row[0], que é o primeiro elemento da lista)
    • ou seja, este for vai adicionando o 1, depois o 3, depois o 5 e por fim o 7, todos em uma mesma lista
    • depois, esta lista [1, 3, 5, 7] é adicionada em transpose
  • na segunda iteração, i vale 1, e agora linha será uma lista com o segundo elemento de cada sub-lista de matrix

Neste caso, achei "errado" o uso de range(2), pois o código só funciona se todas as sublistas de matrix têm exatamente dois elementos (se tiver mais, eles seriam ignorados). Uma forma um pouco mais pythônica, sem depender de um valor fixo, seria:

matrix = [[1, 2], [3, 4], [5, 6], [7, 8]]
transpose = []
for row in zip(*matrix):
    transpose.append(list(row))

print(transpose) # [[1, 3, 5, 7], [2, 4, 6, 8]]

zip serve para percorrer várias listas de uma vez, retornando tuplas contendo os elementos de cada uma delas. Ao passar *matrix, com o asterisco, estou fazendo o unpacking, ou seja, é como se eu passasse cada uma das sub-listas como argumento para zip.

Com isso, na primeira iteração do for, a variável row será uma tupla contendo o primeiro elemento de cada uma das sub-listas. Na segunda iteração, será uma tupla contendo o segundo elemento de cada uma e assim por diante.

Depois, dentro do loop, eu transformo esta tupla em uma lista e adiciono em transpose.

Se quiser, também pode usar uma list comprehension:

transpose = [ list(row) for row in zip(*matrix) ]

Claro que dá para melhorar mais, pois o código não verifica se todas as sub-listas possuem o mesmo tamanho, etc (ou seja, ele assume que a matriz está corretamente preenchida). Mas a ideia básica é essa.

Correct answer by hkotsubo on September 26, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP