{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "O Python é uma linguagem interpretada. Podemos fornecer comandos ao interpretador, que serão executados imediatamente (não existe uma fase de compilação)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2 + 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1 Tipos de dados" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Existem três tipos numéricos primitivos em Python:\n", "- Inteiros\n", "- Números de ponto flutuante\n", "- Números complexos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.1 Inteiro" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A única novidade dos números inteiros é que eles têm precisão ilimitada (podemos representar um número tão grande quanto o computador e o interpretador consigam)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "12" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "-12" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "10000000000000000000000000000 - 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.2 Ponto flutuante" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Os números de ponto flutuante são sempre de precisão dupla (64 bits)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2.3e-5" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "0.42" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "-12.760113" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ ".5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.3 Complexo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Números complexos podem ser representados pela notação cartesiana, colocando um `j` após o valor da parte imaginária." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2 + 3j" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "0.45 - 1.2e3j" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2 Operações" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "O Python entende todos os operadores aritméticos tradicionais para todos os tipos numéricos acima. A exponenciação é representada por `**`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "1 + 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "1 - 4" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "3 * 4" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2 / 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Como vemos acima, a divisão de números inteiros **resulta em um número de ponto flutuante**." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2 ** 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "3.2 - 1.4" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "3.2 - 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "3.2 - (1 - 4J)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "scrolled": true }, "outputs": [], "source": [ "13 / 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(1+2j)/(1-1j)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A divisão inteira pode ser conseguida pelo operador `//`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "13 // 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "O resto da divisão inteira é calculado pelo operador `%`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "13 % 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A divisão inteira arredonda para baixo (isto é, para $-\\infty$):" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "-13 // 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "O resto é sempre compartível com a divisão `(a // b) * b + (a % b) == a`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "-13 % 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Um outro jeito de entender a relação entre a divisão inteira e o resto é que o resto está sempre entre 0 e o divisor." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "13 // -3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "13 % -3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3 Condicionais" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Blocos de comandos são representados em Python pela quantidade de **espaço em branco** antes dos comandos do bloco.\n", "\n", "O comando condicional é representado por um `if` seguido da condição e de dois pontos, com os comandos a serem executados caso a condição seja verdadeira delimitados pela quantidade de espaço em branco." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "if 2 < 3:\n", " print('Ufa, ainda bem!')\n", " print('Fiquei assustado por um tempo.')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "if 2 >= 3:\n", " print('O que está acontecendo aqui?')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Colocamos um bloco dentro de outro bloco aumentando a quantidade de espaço em branco." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = 3\n", "if x > 0:\n", " print('Positivo')\n", " if x % 2 == 0:\n", " print('Par')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para indicar comando a executar caso a condição seja falsa, usamos o comando `else`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "if 2 < 3:\n", " print('Tudo certo')\n", "else:\n", " print('Problemas')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Outro comando associado com o if é o `elif` que indica uma outra condição a testar, *caso a condição anterior tenha sido falsa*." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = 1\n", "if x < 0:\n", " print('Negativo')\n", "elif x > 0:\n", " print('Positivo')\n", "else:\n", " print('Nulo')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4 Repetição" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Uma repetição é indicada pelo comando `while`, que tem sintaxe similar à do `if`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "n = 10\n", "while n > 0:\n", " print(n)\n", " n -= 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5 For" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ao contrário de C, onde o `for` é apenas uma outra forma de escrever um `while`, o `for` de Python tem uma semântica diferente. No `for` se especifica uma variável e uma sequência de valores. Cada um dos valores da sequência será atribuído (em ordem e um por vez) à variável, e então o bloco de comandos dentro do `for` será executado.\n", "\n", "Por exemplo:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for x in [2, 3, 5, 7, 11, 13]:\n", " print(x, x**2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "trans = {'a': 'primeiro', 'b': 'segundo', 'c': 'terceiro'}\n", "for k in trans:\n", " print(k, trans[k])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note no resultado acima: *a ordem em que os elementos são percorrido é determinada pelo gerador da sequência*. No caso de listas, serão gerados os elementos na ordem em que eles se encontram na lista, mas em dicionários (mais sobre eles adiante) a ordem depende de como eles são armazenados internamente.\n", "\n", "Bastante útil com o `for` é a sequência `range`, que tem o formato\n", "\n", " range(inicio, final, passo)\n", "\n", "e gera um conjunto de valores igualmente espaçados. Aqui, `inicio` indica o primeiro valor a gerar, `final` indica o valor onde se para de gerar (esse valor **não será incluído entre os gerados**) e `passo` é a separação de um valor para o próximo. Podemos omitir `passo`, e seu valor será assumido como 1. Podemos adicionalmente omitir `inicio` e seu valor será assumido como 0.\n", "\n", "Veja os exemplos:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for i in range(2, 10, 2):\n", " print(i)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for i in range(2, 10):\n", " print(i)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for i in range(10):\n", " print(i)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for i in range(10, 2, -2):\n", " print(i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarmente útil é o gerador `enumerate`, que percorre uma dada sequência e gera pares índice/valor para essa sequência (os pares são tuplas com dois elementos; mais sobre tuplas adiante).\n", "\n", "Veja o exemplo:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "valores = [2, 3, 5, 7, 11, 13, 17, 19]\n", "for i, x in enumerate(valores):\n", " print(i, ': ', x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6 Variáveis" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Variáveis não precisam ser declaradas. Uma variável em Python passa a existir no momento em que atribuímos um valor a ela.\n", "\n", "Na verdade, a variável recebe uma *referência* a um *objeto* que tem o valor atribuido. Uma referência é similar a um ponteiro em C. Uma variável pode referenciar objetos de qualquer tipo." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = 12" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "print(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = 2 + 5j" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7 Estruturas de dados" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Existem algumas estruturas de dados pré-definidas que são bastante úteis:\n", "- Listas\n", "- Dicionários\n", "- Conjuntos\n", "- Tuplas" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 7.1 Listas" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Listas são listas ligadas com diversos elementos armazenados sequencialmente, na qual podemos com facilidade inserir ou retirar elementos.\n", "\n", "A lista na verdade guarda referências para os objetos (da mesma forma que as variáveis).\n", "\n", "Representamos uma lista usando `[` e `]` com os elementos separados por vírgulas." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares = [0, 2, 4, 6, 8, 10]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Uma lista pode ser indexada para acessar um elemento arbitrário." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares[1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "O índice fornecido é verificado: Se ele for inválido, um erro será gerado, interrompendo a execução do programa." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares[6]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos descobrir o número de elementos na lista com a função `len`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "len(primeiros_pares)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Índices para as listas podem ser negativos. Neste caso, eles contam de trás para frente a partir do último elemento (o último é o índice -1)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares[-1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares[-2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Índices negativos também são verificados." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares[-7]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se quisermos encontrar índice de um elemento numa lista que tenha um valor especificado, podemos usar o método `index`, com a sintaxe abaixo (lista seguida de ponto seguida do nome do métodos seguido dos argumentos entre parêntesis)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares.index(8)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se o elemento procurado não existe, o método `index` gera um erro (exceção)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "primeiros_pares.index(12)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos também acrescentar novos elementos no final das listas, usando o método `append`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares.append(12)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_pares" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "primeiros_pares.index(12)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 7.2 Dicionários" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Outra estrutura de dados é o chamado dicionário. Ele é uma estrutura que guarda pares chave/valor, associando um valor para cada chave fornecida. Chaves e valores podem ser qualquer objeto. Podemos depois consultar o dicionário para encontrar o valor associado a uma chave.\n", "\n", "A sintaxe é com `{` e `}` e pares chave/valor separados por vírgula; cada par chave/valor é representado pela chave, um \"dois pontos\" e o valor." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "telefones = {\"ana\": 123, \"beto\": 456, \"carlos\": 789, \"bento\": 543}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para encontra o valor associado com uma chave usamos a sintaxe de indexação." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "telefones['beto']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos também mudar o valor associado a uma chave através dessa sintaxe." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "telefones['carlos'] = 333" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As chaves são verificadas: se uma chave for solicitada para a qual nenhum valor foi fornecido, será gerado um erro." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "telefones['pedro']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Por outro lado, podemos fornecer o valor para uma nova chave." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "telefones['pedro'] = 7777" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "telefones" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Os valores são de tipos arbitrários. Por exemplo, o comando seguinte associa uma lista à chave `'ana'`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "telefones['ana'] = [123, 422]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "telefones" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "telefones['ana'][1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "telefones['ana']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 7.3 Conjuntos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Conjuntos são uma simplificação de dicionários que têm apenas chaves (sem valor associado). A vantagem dos conjuntos é que eles têm apenas uma cópia de cada elemento que for colocado neles." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_primos = {2, 3, 5, 7, 11, 13}" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "primeiros_inteiros = {0, 1, 2, 3, 4, 5}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos fazer algumas operações de conjuntos. Por exemplo, verificar se um elementos pertence a um conjunto:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "9 in primeiros_primos" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "4 in primeiros_inteiros" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ou fazer a interseção de dois comjuntos." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "primeiros_primos & primeiros_inteiros" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ou a união de conjuntos." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "primeiros_primos | primeiros_inteiros" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ou a diferença de conjuntos." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "primeiros_inteiros - primeiros_primos" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "primeiros_primos - primeiros_inteiros" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ou verificar se um conjunto é subconjunto de outro (`<` é usado para representar a relação de subconjunto)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "primeiros_primos < primeiros_inteiros" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "{1, 2} < primeiros_inteiros" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se transformamos uma lista em conjunto, todos os valores duplicados são eliminados:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "alguns = [1, 2, 3, 4, 5, 2, 3, 4, 5, 3, 4, 5, 4, 5, 5]\n", "unicos = set(alguns)\n", "print(alguns, unicos, sep='\\n')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Isso pode ser usado para eliminar duplicados de uma lista:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "so_alguns = list(set(alguns))\n", "so_alguns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 7.4 Tuplas" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Por fim, tuplas são sequências de valores de um tamanho fixo. Exemplos de tuplas são duplas:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "lados = (5, 7)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ou triplas:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "triangulo = (3, 4, 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Os elementos das tuplas podem ser acessados por indexação:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lados[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mas, contrariamente a listas, não podemos alterar os elementos referenciados pelas tuplas. Dizemos que as tuplas são **imutáveis**." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lados[0] = 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8 Funções" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Novas funções podem ser definidas usando o comando `def`, seguido do nome da função e da lista de argumentos. Os argumentos, como tradicional em Python, não precisam indicar seus tipos.\n", "\n", "A função executa até terminar o bloco ou encontrar um `return`. O `return` especifica o valor a ser retornado pela função." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def poli_1(x):\n", " return 2*x**2 - 5 * x + 8" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "poli_1(2.5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def contagem(n):\n", " while n > 0:\n", " print(n)\n", " n -= 1\n", " print('Acabou')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "contagem(5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def H(n):\n", " s = 0.0\n", " for i in range(1, n+1):\n", " s += 1 / i\n", " return s" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "H(3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "H(1000)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "H(1000000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 9 Cadeias de caracteres" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cadeias de caracteres podem ser criadas delimitadas por `\"` ou `'`. Tanto faz o delimitador usado, desde que o usado para o fechamento seja o mesmo usado para a abertura." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "nome = 'Mecânica Clássica Computacional'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "codigo = \"7600033\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "potus = 'Donald \"Twitter Troll\" Trump'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(potus)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cadeias podem ser indexadas da mesma forma que listas." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[10]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Outra forma de indexar (também válida em listas) é através de *slices*. Um slice é representado por\n", "\n", " inicio:final:passo\n", "\n", "e indica um conjunto de índices, com significado similar ao de `range`. Podemos omitir qualquer dos três elementos. Se `passo` é omitido, ele é assumido 1. se `inicio` é omitido, é assumido 0 e se `final` é omitido, é assumido que pegamos tudo até o final da cadeia." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[0:8]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[:8]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[18:]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[-1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[-2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A indexação é por caracteres UTF-8 (o padrão no Python), e não por bytes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[4]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[3:-3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nome[3:-3:2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Um método útil de cadeias de caracteres é o método `strip`, que elimina todos os espaços em branco no começo e no final de uma cadeia. Temos também o `rstrip` que limpa apenas o final e o `lstrip` que limpa apenas o começo." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "linha = ' Primeiro 10 143.2 '" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "linha.strip()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "linha.rstrip()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "linha.lstrip()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Como se percebe acima, os métodos devolvem uma nova cadeia, deixando a cadeia original intacta.\n", "\n", "Outro método útil é o `split`, que permite quebrar a cadeia em uma lista de subcadeias de acordo com um separador. Se o separador não é especificado, separa-se por espaços em branco (espaços consecutivos são considerados um separador, e mudanças de linha e tabulações contam como espaços)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "linha.split()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "linha.split('10')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "linha.split(' ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A operação oposta ao `split` é feita pelo método `join`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "palavras = linha.split()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "palavras" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "' '.join(palavras)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "', '.join(palavras)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 10 Arquivos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Arquivos podem ser abertos para leitura pela função `open`. Após isso, podemos ler seu conteúdo usando diversos métodos, como o `read` (que lê todo o arquivo como uma cadeia única) ou o `readlines` que lê uma linha por vêz como uma cadeia, retornando uma lista com todas as linhas.\n", "\n", "Quando não precisamos mais do arquivo, devemos fechá-lo com o método `close`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "arq = open('teste.txt')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "tudo = arq.read()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tudo" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "arq.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Quando usamos `open` com apenas o nome do arquivo, como acima, o arquivo é aberto para leitura, pois essa chamada é equivalente a especificar um segundo parâmetro `'r'`, como abaixo." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "arq = open('teste.txt', 'r')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for linha_arq in arq.readlines():\n", " print('Esta é a linha:', linha_arq)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "arq.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Na verdade, o uso explícito de `close` não é recomendado em diversos casos, devido a possíveis problemas com situações de erro. A forma recomendada de lidar com arquivos (entre outros casos similares) é através do uso do comando `with`, como no código abaixo:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "with open('teste.txt') as arq:\n", " for i, linha_arq in enumerate(arq.readlines()):\n", " print('Esta é a linha', i, '=>', linha_arq)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "O `with` faz a atribuição do valor retornado pelo `open` para a variável especificada depois do `as` e se responsabiliza por fazer o `close` quando a execução sai do seu bloco (não importa por qual caminho, mesmo que seja por um erro)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para abrir um arquivo para escrita, basta usar `'w'` ao invés de `'r'`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "with open('saida.txt', 'w') as arq:\n", " print('Olá, caro novo usuário', file=arq)\n", " print('Seja bem vindo', file=arq)\n", " print('3 elevado a 27 vale', 3 ** 27, file=arq)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 11 Módulos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Muitas das funcionalidades de Python são fornecidas através de módulos, que são coleções de funções, classes e objetos que podem ser utilizados pelo programador. Por exemplo, para interface com o sistema operacional (`sys`); para dias e horas (`datetime`); operações matemáticas em ponto flutuante (`math`), entre inúmeros outros. Para usar as funcionalidades fornecidas por esses módulos, precisamos importá-los:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import math # Impora tudo o que o módulo math define\n", "pi = 4 * math.atan(1) # math.atan é uma função que calcula arco-tangente\n", "print(pi)\n", "print('Isso o Python já sabia:', math.pi) # math.pi é uma constante" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 12 Alguns brindes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ao construir uma lista com valores desejados, temos várias opções. Uma delas é fornecer os valores manualmente." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pares_menores_que_20 = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n", "print(pares_menores_que_20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Outra é calcular os valores e colocá-los numa lista:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pares_menores_que_20 = []\n", "corrente = 0\n", "while corrente < 20:\n", " pares_menores_que_20.append(corrente)\n", " corrente += 2\n", "print(pares_menores_que_20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nesses casos simples, onde as repetições do loop são regulares, é sempre melhor usar um `for`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pares_menores_que_20 = []\n", "for corrente in range(0, 20, 2):\n", " pares_menores_que_20.append(corrente)\n", "print(pares_menores_que_20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Na verdade, vemos que os valores inseridos na lista são simplesmente os valores gerados pela `range`. Então, basta converter a range para uma lista:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pares_menores_que_20 = list(range(0, 20, 2))\n", "print(pares_menores_que_20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Uma outra forma de gerar listas diretamente é através da chamada *list comprehension*:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pares_menores_que_20 = [i for i in range(0, 20, 2)]\n", "print(pares_menores_que_20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A sintaxe inclui uma expressão para o cálculo do valor a ser inserido na lista (no exemplo apenas o valor da variável `i`), a palavra-chave `for` o nome da variável usada na expressão (no exemplo `i`) e a palavra-chave `in` seguida de um gerador de valores (no exemplo o `range`).\n", "\n", "É claro que para esse caso simples, é mais fácil usar a conversão direto da range para uma lista, como no exemplo acima, mas quando os cálculos são mais complexos, o uso de *list comprehension* fica interessante:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "potencia_2_de_alguns_pares = [2 ** i for i in range(0, 20, 2)]\n", "print(potencia_2_de_alguns_pares)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos usar sintaxes similares para gerar conjuntos ou dicionários:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "pares_ate_20 = {i for i in range(0, 20, 2)} # O mesmo que set(range(0, 20, 2))\n", "impares_ate_20 = {i for i in range(1, 20, 2)} # O mesmo que set(range(1, 20, 2))\n", "print('Pares:', pares_ate_20)\n", "print('Impares:', impares_ate_20)\n", "print('Todos:', pares_ate_20 | impares_ate_20) # O operador | é a união de conjuntos\n", "\n", "tabela_quadrados = {i: i**2 for i in range(10)}\n", "print(tabela_quadrados)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Quando precisamos uam função simples (apenas um cálculo retornando um valor), não precisamos definir a função através de um `def`, mas podemos usar funções *lambda*, como abaixo." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "meu_poli = lambda x: 2 * x**2 - 3*x + 5\n", "\n", "for i in range(7):\n", " print(meu_poli(i))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Essas funções podem usar não apenas constantes e os parâmetros, como no exemplo acima, mas também outros elementos definidos no contexto em que elas são criadas." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "g = 9.82\n", "tmax = lambda v0: v0/g\n", "\n", "print('Na Terra, para', 10, 'm/s, volta em', 2*tmax(10), 's')\n", "\n", "g = 1.624\n", "print('Mas na Lua, para', 10, 'm/s, volta em', 2*tmax(10), 's')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Note como isso é muito perigoso e pode gerar dificuldades de interpretar resultados!** No caso acima, o ideal é que `g` seja também um parâmetro." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Algumas funções interessantes adicionais:\n", "\n", "- `abs(x)`: valor absoluto de `x`.\n", "- `all(it)`: retorna `True` se todos os valores em `it` forem `True` (ou equivalentes) ou se `it` for vazio.\n", "- `any(it)`: retorna `True` se qualquer dos elementos de `it` for `True`.\n", "- `chr(x)`: retorna caracter correspondente ao código inteiro `x`.\n", "- `input(st)`: Mostra mensagem `st`, aguarda dados lidos do usuário e os retorna.\n", "- `map(f, it)`: aplica a função `f` a cada um dos valores retornados pelo iterador `it` e retorna um iterador com os valores correspondentes.\n", "- `max(it)`: retorna o maior valor de `it`.\n", "- `min(it)`: retorna o menor valor de `it`.\n", "- `ord(c)`: retorna inteiro correspondente a código Unicode do caracter `c`.\n", "- `pow(x, y)`: equivalente a `x ** y` (mais adequado em algumas situações).\n", "- `reversed(it)`: fornece os valores de `it` em ordem revertida.\n", "- `round(x, n)`: arredonda `x` para `n` dígitos depois da vírgula. Se `n` não é fornecido, ele é assumido 0.\n", "- `sorted(it)`: fornece os valores de `it` em ordem crescente (ver também outros parâmetros na documentação).\n", "- `sum(it)`: retorna a soma dos valores de `it`.\n", "- `zip(it1, it2)`: retorna pares com um elementos de `it1` e um elementos de `it2`, até um dos iteradores terminar.\n", "\n", "Veja exemplos abaixo." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x, y, z = 2, -3.4, 3 + 4j\n", "print('1:', abs(x), abs(y), abs(z))\n", "\n", "meus_valores = [1, 3, 5, 2, 4, 6, -7, -3, 0]\n", "print('2:', all(meus_valores), any(meus_valores), all(meus_valores[:8]))\n", "\n", "print('3:', min(meus_valores), max(meus_valores))\n", "\n", "print('4:', sum(meus_valores))\n", "\n", "print('5:', list(reversed(meus_valores)), list(sorted(meus_valores)))\n", "\n", "print('6:', list(map(lambda x: 3*x + 2, meus_valores)))\n", "\n", "ic = ord('c')\n", "x = chr(ic + 2)\n", "print('7:', ic, x)\n", "\n", "nome = input('Qual seu nome?')\n", "print('8:', 'Bem vindo, '+ nome+'!')\n", "print('9:', ''.join(map(lambda c: chr(ord(c) + 1), nome)))\n", "\n", "meu_pi = 3.14159265\n", "print('10:', meu_pi, round(meu_pi), round(meu_pi, 2), round(meu_pi, 4), round(meu_pi, 6))\n", "\n", "print('11:', end=' ')\n", "for a, b in zip(meus_valores, reversed(meus_valores)):\n", " print(a, ':', b, sep='', end=', ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 13 CUIDADO: Referências!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tanto variáveis como listas, tuplas e dicionários (além de outras estruturas de dados), guardam **referências** para objetos que têm os valores especificados. Lembre-se disso, para poder entender corretamente o funcionamento de codigos Python." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = [1, 2, 3] # a é uma referência para essa lista alegre\n", "b = a # b é o mesmo que a, quer dizer, uma referência para a mesma lista. O objeto de lista é o mesmo!\n", "b[2] = 4 # Mudando o elementos de índice 2 da lista referenciada por b\n", "print('b vale:', b) # Veja o que é mostrado\n", "print('a vale:', a) # E aqui!!!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Isso acontece pois, como escrito nos comentários, ao alterarmos `b[2]` estamos alterando o elemento de índice 2 da lista **referenciada** por `b`, que por acaso é a mesma lista referenciada por `a`. Isso vai acontecer com qualquer operação que altere a lista." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a.append(8)\n", "print('a vale:', a)\n", "print('b vale:', b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mas se mudarmos a referência de uma das variáveis, então elas não são mais relacionadas:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b = [3, 4]\n", "print(a, b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "No caso acima, a primeira atribuição faz a variável `b` referenciar a nova lista (com os valores 3 e 4), e portanto deixar de referenciar a lista anterior. Mas a variável `a` não foi afetada, e continua referenciando a mesma lista." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ou veja este caso um pouco mais elaborado:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def valor_absoluto(lista_original):\n", " lista_nova = lista_original\n", " for i, x in enumerate(lista_nova):\n", " lista_nova[i] = abs(x)\n", " return lista_nova\n", "\n", "minha_lista = [0, 1, -2, 3, -4, -5, 6, 7, -8]\n", "sem_negativo = valor_absoluto(minha_lista)\n", "print('Aqui nenhum negativo:', sem_negativo)\n", "print('E esta é a original:', minha_lista)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "No código abaixo, está uma tentativa de implementar um algoritmo que requer a iteração de valores em uma lista até que entre o valor atual e o anterior não haja uma diferença absoluta maior do que 0.0001.\n", "\n", "Veja o resultado. Você consegue explicar o que ocorreu?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "valores = [10., 3., 4., 7., 2., 8., 1., 0.5, 5., 0]\n", "N = len(valores)\n", "diff = 1.0\n", "passos = 0\n", "while diff > 0.0001:\n", " valores_antigos = valores\n", " for i in range(1, N-1):\n", " valores[i] = (valores_antigos[i-1] + 2.0 * valores_antigos[i] + valores_antigos[i+1]) / 4.\n", " diff = 0.\n", " for i in range(N):\n", " diff = max(diff, abs(valores_antigos[i] - valores[i]))\n", " passos += 1\n", "\n", "print('Convergiu para os seguintes valores:', valores)\n", "print('Máxima diferença encontrada:', diff)\n", "print('Número de passos:', passos)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para resolver esse tipo de problema, precisamos garantir que a outra variável receba uma **referência para um novo objeto**, que então pode ter seu valor alterado sem alterar o objeto original. Para isso, usamos o método `copy`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = [1, 2, 3]\n", "b = a.copy()\n", "b[2] = 4\n", "print('a vale', a)\n", "print('b vale', b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mas **cuidado**! Isso nem sempre é suficiente. Mais especificamente, o `copy` faz uma cópia do objeto, mas se esse objeto contém referências, ele simplesmente copia as referência..." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c = [[1, 2], [2, 4], [3, 6]]\n", "d = c.copy()\n", "d[0][1] = 314\n", "print('c vale', c)\n", "print('d vale', d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Isso porque `d[0]` é uma referência para uma lista, que por acaso é a mesma referenciada por `c[0]`. Portanto, ao alterarmos `d[0][1]` estamos também alterando `c[0][1]`!\n", "\n", "Para esses casos, a saída geral (apesar de que podem haver soluções mais eficientes para cada problema específico) é usar a função `deepcopy` do módulo `copy`, que faz recursivamente uma cópia sempre que acha uma referência. Neste caso, como ele sabe que cada `c[i]` é uma referência, ele faz cópias de cada uma dessas listas:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import copy\n", "c = [[1, 2], [2, 4], [3, 6]]\n", "d = copy.deepcopy(c)\n", "d[0][1] = 314\n", "print('c vale', c)\n", "print('d vale', d)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.1" } }, "nbformat": 4, "nbformat_minor": 2 }