From f07faa7596d7177852325ef1bed3c167625656d9 Mon Sep 17 00:00:00 2001 From: Henrique Branco Date: Sat, 20 Jul 2024 23:31:49 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20continuidade=20cap=C3=ADtulo=20listas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- book/06-estruturas-de-dados/02-listas.ipynb | 589 +++++++++++++++++++- 1 file changed, 579 insertions(+), 10 deletions(-) diff --git a/book/06-estruturas-de-dados/02-listas.ipynb b/book/06-estruturas-de-dados/02-listas.ipynb index 9270bc6..068e4c2 100644 --- a/book/06-estruturas-de-dados/02-listas.ipynb +++ b/book/06-estruturas-de-dados/02-listas.ipynb @@ -51,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -76,7 +76,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -108,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -139,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -167,17 +167,17 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Primeira lista interna: [1]\n", - "Segunda lista interna: [2, 3]\n", - "Terceira lista interna: [4, 5, 6]\n", - "Quarta lista interna: [7, 8, 9, 10]\n" + "Primeiro elemento da lista: [1]\n", + "Segundo elemento da lista: [2, 3]\n", + "Terceiro elemento da lista: [4, 5, 6]\n", + "Quarto elemento da lista: [7, 8, 9, 10]\n" ] } ], @@ -199,7 +199,576 @@ { "cell_type": "markdown", "metadata": {}, - "source": [] + "source": [ + "## Métodos de listas" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Diferentemente de string, listas tem relativamente poucos métodos, 11 no total, conforme consta na [documentação oficial dos métodos de lista](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists). Por este motivo, é possível cobrí-los todos aqui." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Adição de elementos" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Existem 3 métodos para trabalhar com adição de elementos à uma lista:\n", + "\n", + "- `append( )`: Adiciona um item ao final da lista.\n", + "- `extend( )`: Adiciona todos os itens de uma outra sequencia ao final da lista.\n", + "- `insert( )`: Insere um item em uma posição específica.\n", + "\n", + "Vamos ver em detalhes cada um deles." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Append" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "O método `append(x)` adiciona um dado objeto `x` ao final da lista." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['maçã', 'banana', 'laranja', 'uva']\n" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\"]\n", + "frutas.append(\"uva\")\n", + "print(frutas)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notem que o objeto como um todo, no caso a string `uva`, foi adicionada como um objeto único (uma única string) ao final da lista." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Extend" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "O método `extend(x)` estende a lista adicionando todos os itens, um a um, de uma outra sequencia. Ele funciona diferente do método `append(x)` que adiciona o objeto inteiro." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['maçã', 'banana', 'laranja', 'uva']\n" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\"]\n", + "outras_frutas = [\"laranja\", \"uva\"]\n", + "frutas.extend(outras_frutas)\n", + "print(frutas)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "No exemplo, `outras_frutas` é uma segunda lista, e os elementos desta listas, `laranja` e `uva`, são adicionados à lista `frutas`. O `extend` meio que varre uma dada sequencia, e adiciona os elementos um a um na lista. \n", + "\n", + "Vamos entender melhor com mais um exemplo. Se no exemplo do `append()` nós só trocássemos pelo `extend()`, veja o que aconteceria:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['maçã', 'banana', 'laranja', 'u', 'v', 'a']\n" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\"]\n", + "frutas.extend(\"uva\")\n", + "print(frutas)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Relembrando que uma string é uma sequencia também, só que de caracteres. Quando passamos a string `uva` para o `extend` em `frutas.extend(\"uva\")`, o que estamos dizendo é: pegue cada elemento (caracter) da string `uva` e adicione um a um à lista `frutas`. \n", + "\n", + "É diferente do método `append` que em `frutas.append(\"uva\")` nós estamos dizendo: adicione a string inteira `uva` como um objeto único ao final da lista.\n", + "\n", + "Conseguiram compreender tal diferença?\n", + "\n", + "Como o `extend` necessariamente varre uma sequência, não é possível estender uma lista a partir de algo que não seja uma sequência, gerando o erro abaixo" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "tags": [ + "raises-exception" + ] + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "'int' object is not iterable", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[22], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m lista_de_numeros \u001b[38;5;241m=\u001b[39m [\u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m2\u001b[39m, \u001b[38;5;241m3\u001b[39m, \u001b[38;5;241m4\u001b[39m, \u001b[38;5;241m5\u001b[39m]\n\u001b[1;32m----> 2\u001b[0m \u001b[43mlista_de_numeros\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mextend\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m6\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(lista_de_numeros)\n", + "\u001b[1;31mTypeError\u001b[0m: 'int' object is not iterable" + ] + } + ], + "source": [ + "lista_de_numeros = [1, 2, 3, 4, 5]\n", + "lista_de_numeros.extend(6)\n", + "print(lista_de_numeros)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "O erro `TypeError: 'int' object is not iterable` informa justamente que o tipo `int` proveniente do `6` passado para o `extend` não é uma sequência.\n", + "\n", + "Já o `append` não precisa necessariamente receber uma sequência, pois ele adiciona o objeto em si, e não os elementos de uma dada sequência." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6]\n" + ] + } + ], + "source": [ + "lista_de_numeros = [1, 2, 3, 4, 5]\n", + "lista_de_numeros.append(6)\n", + "print(lista_de_numeros)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Para finalizar, um último exemplo mostrando adição de uma lista à outra lista com `append` e `extend`." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, [6, 7, 8, 9]]\n" + ] + } + ], + "source": [ + "lista_de_numeros = [1, 2, 3, 4, 5]\n", + "lista_de_numeros.append([6, 7, 8, 9])\n", + "print(lista_de_numeros)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8, 9]\n" + ] + } + ], + "source": [ + "lista_de_numeros = [1, 2, 3, 4, 5]\n", + "lista_de_numeros.extend([6, 7, 8, 9])\n", + "print(lista_de_numeros)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Conforme exemplificados acima, o `append` adiciona a lista `[6, 7, 8, 9]` como um objeto único, um elemento a mais na lista inicial, obtendo como resultado uma lista aninhada. O tamanho da lista final é o tamanho da lista inicial + 1 elemento.\n", + "\n", + "No caso do `extend`, os elementos da lista `[6, 7, 8, 9]` são adicionados um a um à lista inicial. O tamanho da lista final é é o total de elementos da lista inicial + o total de elementos da lista estendida." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Insert" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Tanto o `append` quanto o `extend` só adicionam/estendem elementos ao final da lista. O `insert` tem o mesmo comportamento do `append`, sendo possível especificar o índice na qual o elemento será inserido.\n", + "\n", + "Nesta altura do livro, espero que você tenha entendido e se lembre que **a indexação em Python começa por 0!**" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['maçã', 'morango', 'banana', 'laranja']\n" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\"]\n", + "frutas.insert(1, \"morango\")\n", + "print(frutas)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Remoção de elementos" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Para remoção de elementos, também temos 3 métodos:\n", + "\n", + "- `remove( )`: Remove a primeira ocorrência de um item da lista.\n", + "- `pop( )`: Remove e retorna o item em uma posição específica.\n", + "- `clear( )`: Remove todos os itens da lista." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Remove" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "O método `remove` apaga **a primeira ocorrência da esquerda para direita** de um item da lista." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['maçã', 'laranja', 'banana']\n" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\", \"banana\"]\n", + "frutas.remove(\"banana\")\n", + "print(frutas)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Observem que tínhamos 2 ocorrências de `banana` na lista inicial, nos índices 1 e 3 da lista. A primeira aplicação de `frutas.remove('banana')` removeu apenas `banana` do índice 1." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "tags": [ + "raises-exception" + ] + }, + "outputs": [ + { + "ename": "ValueError", + "evalue": "list.remove(x): x not in list", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[28], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m frutas \u001b[38;5;241m=\u001b[39m [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmaçã\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbanana\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlaranja\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbanana\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[1;32m----> 2\u001b[0m \u001b[43mfrutas\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mremove\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mfruta inexistente\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(frutas)\n", + "\u001b[1;31mValueError\u001b[0m: list.remove(x): x not in list" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\", \"banana\"]\n", + "frutas.remove(\"fruta inexistente\")\n", + "print(frutas)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Caso o elemento não seja encontrado, o nosso código vai apresentar o erro com a mensagem `ValueError: list.remove(x): x not in list`, informando que o elemento passado não está na lista" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "O método `pop` **remove** e **retorna** o item em um índice específico.\n", + "\n", + "O `pop` atua diferente do `remove`. No `remove` passamos o elemento em si, e no `pop` passamos a posição do elemento que será removido, e não o elemento em si." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['banana', 'laranja']\n" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\"]\n", + "frutas.pop(0)\n", + "print(frutas)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Além disso, há outra diferença. No caso do `remove`, não conseguimos salvar o elemento removido em uma variável, pois ele não é retornado. Já no `pop`, o elemento removido é retornado, sendo possível salvá-lo em uma variável para uso posterior. Vejamos exemplos:\n", + "\n", + "Quando salvamos o resultado de `frutas.remove(\"banana\")` na variável `fruta_removida`, ela não recebe nenhum valor, e acaba representanda pelo valor nulo `None` em Python." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "None\n" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\", \"banana\"]\n", + "fruta_removida = frutas.remove(\"banana\")\n", + "print(fruta_removida)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Porém, quando salvamos o resultado de `frutas.pop(0)` na variável `fruta_removida`, ela recebe o valor do elemento removido. Por isso frisei a funcionalidade do `pop` como remove **e retorna** o item pela posição. " + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "maçã\n", + "['banana', 'laranja', 'banana']\n" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\", \"banana\"]\n", + "fruta_removida = frutas.pop(0)\n", + "print(fruta_removida)\n", + "print(frutas)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Quando nenhum índice é passado para o `pop`, ele remove e retorna o último elemento da lista por padrão." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "banana\n", + "['maçã', 'banana', 'laranja']\n" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\", \"banana\"]\n", + "fruta_removida = frutas.pop()\n", + "print(fruta_removida)\n", + "print(frutas)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Informações sobre a lista" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Aqui temos 2 métodos:\n", + "\n", + "- `index()`: Retorna o índice da primeira ocorrência de um item.\n", + "- `count()`: Retorna o número de ocorrências de um item na lista." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Index" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "O método `index` é bem simples e serve para buscar pelo menor índice de um dado elemento, sendo muito útil em localizar a posição de itens em uma lista. No exemplo abaixo, o primeiro índice encontrado para `banana` é o índice 1." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Menor índice encontrado: 1\n" + ] + } + ], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\", \"banana\"]\n", + "indice = frutas.index(\"banana\")\n", + "print(\"Menor índice encontrado:\", indice)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Caso o elemento não seja encontrado, o erro `ValueError` equivalente ao `remove` aparecerá." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {"tags": [ + "raises-exception" + ]}, + "outputs": [], + "source": [ + "frutas = [\"maçã\", \"banana\", \"laranja\", \"banana\"]\n", + "indice = frutas.index(\"banana\")\n", + "print(\"Menor índice encontrado:\", indice)" + ] } ], "metadata": {