Skip to main content

Introdução parte 1


O Python é uma linguagem de programação de alto nível que foi desenvolvida por Guido van Rossum em 1991. Nós podemos usar ele apenas como uma linguagem de Script ou podemos desenvolver usando programação orientada a objetos.



Função print


O print é uma função usada para imprimir (mostrar) informações no console (tela/monitor), por padrão cada print exibe apenas uma única linha, mas é possível alterar esse comportamento.


Uma forma de mostrar várias linhas sem usar \n:

print("""linha1
ola
tudo bem? """)

# Resultado: linha1
# ola
# tudo bem?


f-strings


É uma forma moderna e prática de formatar strings. Basta colocar um f antes das aspas e usar {} para inserir variáveis:

nome = "Fulano"
idade = 27
print(f"Meu nome é {nome} e tenho {idade} anos.")


.format()


É uma forma mais antiga de formatar strings, mas ainda pode ser observada em bastante códigos:

nome = "Fulano"
idade = 27
print("Meu nome é {} e tenho {} anos.".format(nome, idade))

Você também pode usar índices:

print("Idade: {1}, Nome: {0}".format(nome, idade))


Operações com string


Por padrão não é possível fazer operações com string, afinal, não da para somar letras ☹️. Mas é possível usar dois operadores com strings, são eles: + e o *, alem deles dois temos a , mas ela não é um simbolo de operação, mas como estamos falando de string vou explicar ela também.


O operador + é usando para concatenar duas strings (junta duas partes como se fossem uma só):

a = 'Abe'
b = 'lha'

print(a + b)

# Resultado: Abelha

O operador * é usando para multiplicar o valor da string antes dela:

a = 'Abe'
b = 'lha'

print(a*3)

# Resultado: AbeAbeAbe

O operador , é usando para unir strings mas diferente do +, ele adiciona um espaço entre as variáveis:

a = 'Abe'
b = 'lha'

print(a,b)

# Resultado: Abe lha


Módulos


Um módulo é um arquivo em Python que contém uma coleção de funções relacionadas. Antes usar um módulo devemos importar ela com o comando abaixo, em outras palavras um módulo é uma biblioteca contendo instruções, funções e classes.

# Importando o módulo math:
import math

# Importando o módulo sys e renomeando:
import sys as sistema

# Importando um método de um módulo:
from sys import exit

# Importando um método de um módulo e renomeando:
from sys import exit as sair


Modularização


A modularização é o processo de dividir seu código em partes menores e organizadas, chamadas módulos, para que ele fique mais legível, reutilizável e fácil de manter. Ao invés de escrever todo o código em um único arquivo, você separa funções, classes e variáveis em arquivos diferentes conforme a função de cada um.


Cada arquivo .py é um módulo, e pode ser importado e usado em outros arquivos com a instrução import.



Como criar e usar módulos


Suponha que você tenha um arquivo chamado matematica.py:

# matematica.py
def somar(a, b):
return a + b

def subtrair(a, b):
return a - b

Você pode usar esse módulo em outro arquivo:

# app.py
import matematica

print(matematica.somar(5, 3)) # 8
print(matematica.subtrair(10, 4)) # 6

Ou importar funções diretamente:

from matematica import somar

print(somar(2, 2)) # 4


Pacotes


Quando você organiza vários módulos em pastas, você tem um pacote. Um pacote é uma pasta com um arquivo especial chamado __init__.py. Mesmo vazio, esse arquivo indica que a pasta é um pacote Python. A estrutura seria assim:

meuprojeto/
├── app.py
└── util/
├── __init__.py
└── matematica.py

E poderiamos importar assim:

from util.matematica import somar

O arquivo __init__.py serve para transformar um diretório em um pacote Python. Isso permite que você importe módulos daquele diretório usando a sintaxe de pacotes (from diretório import modulo). Sem ele, em versões mais antigas do Python (antes do 3.3), o Python nem reconhecia a pasta como um pacote válido.


Desde o Python 3.3, ele não é mais obrigatório para pacotes simples, mas ainda é altamente recomendado, especialmente se você quiser controlar o comportamento de importação ou se vai usar ferramentas como pytest, mypy, ou empacotar o projeto.


Você pode deixá-lo vazio se só quiser marcar a pasta como pacote. Mas pode também colocar importações internas (para facilitar acesso externo):

# __init__.py
from .modulo_a import funcao_a
from .modulo_b import ClasseB

Agora, quem importar o pacote já acessa diretamente:

from pacote import funcao_a, ClasseB

Também pode fazer inicialização de variáveis ou configuração. O código abaixo vai ser executado na hora que o pacote for importado.

# __init__.py
print("Pacote util carregado")
configuracao = {"modo": "debug"}

Definir o que será importado com from pacote import *. Assim, apenas esses nomes serão expostos:

__all__ = ["funcao_a", "ClasseB"]

Você pode carregar arquivos, fazer leitura de configuração, validar ambiente:

import os

if not os.path.exists("/tmp"):
raise RuntimeError("Diretório /tmp obrigatório.")


Modularização interna


Você pode modularizar dentro de um mesmo projeto mesmo sem criar pacotes externos. Separar lógicas como:

  • models.py → classes de dados
  • services.py → regras de negócio
  • utils.py → funções auxiliares
  • main.py → ponto de entrada do programa


Path


Se o módulo está no mesmo diretório, você pode importá-lo diretamente. Mas se não estiver no mesmo diretório, o Python não consegue importar ele, a menos que:

  1. Você diga a ele onde procurar, ou
  2. O diretório esteja num pacote, ou
  3. O caminho esteja no PYTHONPATH ou em sys.path


sys.path


Quando você tenta importar algo, o Python procura esse módulo nos diretórios listados em sys.path, que normalmente incluem:

  • O diretório atual (.)
  • O diretório onde o Python foi instalado
  • Bibliotecas padrão e instaladas com pip
  • Variáveis de ambiente, como PYTHONPATH

Você pode ver isso assim:

import sys
print(sys.path)


Importar de outro diretório (fora do atual)


Se o arquivo que você quer importar não está no mesmo diretório, você precisa adicionar o caminho à lista de busca. Para o exemplo, vamos criar a estrutura abaixo:

meuprojeto/
├── app/
│ └── principal.py
└── lib/
└── util.py

No principal.py, se você tentar importar com o código abaixo, vai dar erro:

import util

ModuleNotFoundError: No module named 'util'

Isso acontece porque lib/ não está no sys.path.


Nesse caso, podemos adicionar o lib no sys.path:

import sys
sys.path.append('../lib')

import util # agora funciona


Transformar em pacote


Você também pode organizar a estrutura como um pacote e usar importação relativa ou absoluta. Coloque um __init__.py nos diretórios:

meuprojeto/
├── app/
│ ├── __init__.py
│ └── principal.py
└── lib/
├── __init__.py
└── util.py

E dentro de principal.py, use:

from lib import util

Mas isso só funciona se você rodar o código a partir da raiz do projeto (no caso, se estiver em meuprojeto), ou usar um gerenciador como python -m.



Usar PYTHONPATH


Você também pode definir o caminho onde o Python deve procurar seus módulos:

export PYTHONPATH=/caminho/para/lib
python app/principal.py

Ou temporariamente:

PYTHONPATH=./lib python app/principal.py

Assim o Python vai conseguir importar util.



Função


Uma função é um pedaço de código que podemos reaproveitar sem ter que escrever ele diversas vezes.

#################################
# Sintaxe #
#################################
def name(<var>):
<statement(s)>


def soma():
num1 = int(input("Digite o primeiro numero: "))
num2 = int(input("Digite o Segundo numero: "))

print(num1 + num2)

soma()

Por padrão a endentação é de quatro espaços.


Quando se cria variáveis dentro de uma função, essas variáveis só vão existir dentro da função, ela é uma variável local daquela função. Para se obter o valor de uma variável de uma função usamos o return, por exemplo:

def teste(nome):
nome = nome + ' Oliveira'
return nome

a = teste('Joao')

print(a)

# Resultado: Joao Oliveira


Função com Argumentos


Passando argumentos para uma função com:

def teste(name):
print(name)

teste('bob')

# Resultado: bob

Função que muda o nome da variável que foi passada para ela, muda apenas o nome da variável.

nome = 'Joao'
sobrenome = 'Eduardo'
ultimo = 'Oliveira'

def teste(S1, S2):
print(S1, S2, ultimo)

teste(nome, sobrenome)

# Resultado: Joao Eduardo Oliveira


In e Not In


Os operadores in e not in são usados para verificar se um valor está ou não dentro de uma estrutura de dados que é iterável, como listas, strings, dicionários, sets, tuplas, entre outros.


Eles retornam um valor booleano (True ou False) e são comumente usados em condições como if e while (também no for, mas o uso é diferente) ou diretamente em expressões.



in


O operador in verifica se um elemento existe dentro de uma sequência ou coleção. Exemplos:

lista = [1, 2, 3]

print(2 in lista) # True
print(5 in lista) # False

texto = "python"

print("py" in texto) # True
print("java" in texto) # False

conjunto = {1, 2, 3}

print(3 in conjunto) # True

No caso de dicionários, o in verifica se a chave existe, não o valor:

d = {"nome": "Fulano", "idade": 27}

print("nome" in d) # True
print("Fulano" in d) # False


not in


É o contrário de in. Verifica se o elemento não está dentro da coleção. Exemplos:

lista = [1, 2, 3]

print(4 not in lista) # True
print(2 not in lista) # False

"z" not in "python"  # True

Esses operadores funcionam em qualquer tipo que implemente o protocolo de iteração (__contains__ ou __iter__), o que inclui praticamente todas as coleções em Python.



Estruturas de repetição


As estruturas de repetição permitem a execução repetida de um bloco de código com base em determinadas condições ou contadores. Essas estruturas são valiosas para automatizar tarefas repetitivas e melhorar a eficiência dos programas.


For


Normalmente usado quando você sabe a quantidade de iteração (repetições) que deverá ocorrer, normalmente usamos array, listas, ranges e outros métodos para controlar isso.

#################################
# Estrutura #
#################################
for <var> in <iterable>:
<statement(s)>


## Usando 'range':
total = 0
vezes = 10
for number in range(vezes):
total = total + 1
print(total)

## Usando uma lista:
fruits = ["apple", "banana", "cherry"]
for lista in fruits:
print(lista)

## Usando as letras de uma string:
for letra in "banana":
print("Letra:", letra)

While


Muito usado quando não sabemos quantas iterações (repetições) serão feitas, para isso usamos alguma variável booleana para determinar quando continuar ou sair do loop.

#################################
# Estrutura #
#################################
<var> = <controller>
while <var> <Comparation> <iterable>:
<statement(s)>

ou
<var> = <controller>
while (<var> <Comparation> <iterable>):
<statement(s)>

# Comparation:
# <
# >
# <=
# >=

idade = int(15)
while (idade <= 40):
idade = int(input("Você é novo, digite a idade de novo: "))


Estruturas de condições


É uma estrutura que permite analisar resultados e com base nisso ter uma ação.



IF


Estrutura de decisão com if.

#################################
# Estrutura #
#################################
if <var> <Comparation> <iterable>:
<statement(s)>
elif <var> <Comparation> <iterable>:
<statement(s)>
else:
<statement(s)>

## O uso de parenteses é opcional para deixar o código mais limpo.


# Condições lógicas usadas no IF:
Igual: a == b
Diferente (não igual): a != b
Menor que: a < b
Menor que ou Igual a: a <= b
Maior que: a > b
Maior que ou Igual a: a >= b


nome = str(input("Digite seu nome: ")) # Exibindo na tela e pegando entrada do teclado.
# Não precisa converter para string, por default, tudo que vier do teclado já é string.

if (len(nome) >= 15): # inicio do if, verifica se a quantidade de letras é maior ou igual a 15.
print("Seu nome é grande.")

elif (len(nome) < 15) and (len(nome) >= 6): # usando operador AND
print("Seu nome tem um tamanho razoável.")

else:
print("Seu nome é pequeno.")

## Extra:
print()
idade = int(input("Digite sua idaide: ")) # igual 'read -p ("") VAR'
# Estou pegando uma entrada do teclado, e convertendo ela para int, depois armazeno na variavel.

Testando se uma variável está vazia:

a = None

if a is None:
print('Variavel vazia.')

else:
print('Variavel nao vazia.')

Testando se uma variável é verdadeira ou falsa:

a = False

if a:
print('Variavel verdadeira.')

else:
print('Variavel falsa.')

Com o mesmo if acima é possível verificar se uma lista está vazia:

lista = []

if not lista:
print('lista vazia!')
else:
print('lista não esta vazia!')

# Resultado: lista vazia!

Usando AND:

a = False
b = False

if a and b:
print('Tudo verdadeiro.')

else:
print('Tudo falso.')

Usando OU:

a = False
b = False

if a or b:
print('Alguém é verdadeiro.')

else:
print('Nenhuma é verdadeira.')

Verificando se o valor de uma variável está dentro de uma lista ou dicionário:

## Primeiro com dicionário:
dici = {'size': 'fat', 'dia': 'feio'}
periodo = 'dia'

if periodo in dici.keys():
print(periodo, 'está dentro do dicionário')

else:
print(periodo, 'não está dentro do dicionário')


## Usando lista (serve com tupla):



Módulo RANDOM


A módulo random é usada para gerar numeros pseudo aleatorios. Vamos usar a função randint para gerar números pseudos aleatórios que sejam inteiros.

#################################
# Sintaxe #
#################################
random.randint(X,M)

# X = Menor número.
# M = Maior número.


import random

for aleatorio in range(5):
print(random.randint(1,100))

# Gerar numeros para a loteria, hehe (entre 1 e 60):
print(random.randint(1,60))


Sample


Usado para retornar um resultado, onde nós escolhemos o tamanho de caracteres que conterá o resultado, mas que o valor que será retornado seja aleatório, basicamente, embaralha a string e retorna um tamanho escolhido. Essa é parte básica dessa função, leia a doc da função para mais detalhes.

#################################
# Sintaxe Básica #
#################################
random.sample(X,M)

# X = É de onde ele vai obter a informação.
# M = É o tamanho do resultado que será retornado.


import random

a = "arroz feijao carne"
random.sample(a, 12)
# ['a', ' ', 'o', 'r', 'c', ' ', 'z', 'a', 'a', 'j', 'e', 'i']

# Agora vamos usar o 'join' para remover essa lista (O valor retornado será uma string):
"".join(random.sample(a, 12))
# 'arr caieeofr'

"".join(random.sample(a, 12))
# 'oja a eorfre'

Veja um exemplo prático dessa função em uso para criar um gerador de senhas.



SYS


O módulo sys é usada para interação com o script a partir de parametros especificos e funções. Isso acontece porque o sys interage com variáveis em uso e suas funções interagem direto com o interpretador.


A função exit é usada encerrar o script (sair do python), igual a: exit 0, exit 1 no bash, também são conhecidos como return codes no bash.

#################################
# Sintaxe #
#################################
sys.exit(N)

# N = Número de erro que será retornado para o Shell.


import sys
num = input("Digite um número de 0 até 10: ")

# Se você colocar 'if not num.isdigit()' - Voce pode ver se é um caractere'
if num.isdigit(): # Nao aceitou INT, verifica se é um número.

if (int(num) >= 0) and (int(num) <= 10):
print("Parabéns")
sys.exit(0)

else:
print("Erro, número deve estar entre 0 e 10")
sys.exit(12)

else:
print("Erro, não foi digitado um número entre 0 até 10")
sys.exit(10)


ARGV


O exemplo abaixo demonstra como usar a função argv do módulo sys. Usado para obter parametros fornecidos via linha de comando ao iniciar o script.

#################################
# Sintaxe #
#################################
sys.argv(N)

# N = Número da posição do argumento na linha de comando.

####### ARQUIVO SCRIPT PYTHON #######
#!/usr/bin/env python3

import sys
arg1 = sys.argv[1]
arg2 = sys.argv[2]

print('Argumento 1:', arg1)
print('Argumento 2:', arg2)
####### ARQUIVO SCRIPT PYTHON #######

# Agora rode o comando:
$ chmod +x teste.py
$ ./teste.py deu-arg1 certo?-arg2
Argumento 1: deu-arg1
Argumento 2: certo?-arg2

Contando o número de argumentos:

#!/usr/bin/env python3

import sys

# Contando a quantidade de Argumentos, faço 'len(sys.argv) - 1' porque ele conta o arg 0,
# que é o nome do script.
print("Voce digitou",len(sys.argv)-1,"Argumentos.")

# Removendo o item 0 da lista, no caso o nome do script:
sys.argv.remove(sys.argv[0])

# Exibindo todos os argumentos:
print("args:",sys.argv)




Exceções


Quando ocorre um erro durante a execução de um programa, dizemos que uma exceção foi lançada. Se esse erro não for tratado, o programa é interrompido imediatamente. Por isso, é importante prever situações que podem causar falhas e implementar formas de lidar com elas.


Em Python, usamos o bloco try para escrever o código que pode causar um erro, e o except para tratar esse erro caso aconteça. Dessa forma, o programa continua funcionando normalmente.

def dividir(divide):
try:
return 42 / divide
except ZeroDivisionError:
print("Erro: divisão por zero não é permitida.")

print(dividir(2)) # 21.0
print(dividir(12)) # 3.5
print(dividir(0)) # Erro: divisão por zero não é permitida.
print(dividir(1)) # 42.0

Nesse exemplo, usamos try para tentar dividir, e except para capturar especificamente o erro ZeroDivisionError, que ocorre ao tentar dividir por zero.



Exception


O except Exception pode ser usado para capturar quase todos os erros que podem acontecer em tempo de execução, ou seja, todas as exceções que herdam da classe Exception, que é a base para a maioria dos erros que você vê no dia a dia: ValueError, TypeError, FileNotFoundError, etc.


Exemplo:

try:
x = int("abc") # isso causa ValueError
except Exception:
print("Algum erro aconteceu")

Esse except Exception vai capturar o ValueError, porque ValueError herda de Exception. Você também pode capturar o objeto da exceção para ver detalhes:

try:
x = int("abc")
except Exception as e:
print("Erro capturado:", e)

Saída:

Erro capturado: invalid literal for int() with base 10: 'abc'

Nem todo erro em Python é uma Exception. Existem algumas exceções que herdam diretamente de BaseException e não são capturadas com except Exception. Exemplos:

  • KeyboardInterrupt (quando o usuário aperta Ctrl+C)
  • SystemExit (quando sys.exit() é chamado)
  • GeneratorExit

Esses casos exigem except BaseException se você realmente quiser capturar tudo:

try:
raise KeyboardInterrupt
except Exception:
print("Não captura") # esse bloco não roda
except BaseException:
print("Capturou com BaseException") # esse sim


else


Se você quiser executar algo somente quando o try não gerar erro, use o else. Ele é útil para separar o tratamento do erro do código que só deve rodar se tudo der certo.

def dividir(divide):
try:
resultado = 42 / divide
except ZeroDivisionError:
print("Erro: divisão por zero.")
else:
print(f"Resultado: {resultado}")

dividir(2) # Resultado: 21.0
dividir(0) # Erro: divisão por zero.


finally


O bloco finally é usado para executar algo no final, independente se houve erro ou não. Ele é muito útil para liberar recursos, fechar arquivos, encerrar conexões, etc.

def dividir(divide):
try:
resultado = 42 / divide
except ZeroDivisionError:
print("Erro: divisão por zero.")
else:
print(f"Resultado: {resultado}")
finally:
print("Finalizando operação.")

dividir(2)
dividir(0)

Saída:

Resultado: 21.0  
Finalizando operação.

Erro: divisão por zero.
Finalizando operação.


raise


Você pode usar raise para forçar o lançamento de uma exceção. Isso é útil quando você quer impedir que algo continue se uma condição não for respeitada. Você pode usar o raise sem nenhum try.

def dividir(dividendo, divisor):
try:
return dividendo / divisor
except ZeroDivisionError:
print("Erro: divisão por zero.")
else:
print(f"Resultado: {resultado}")

valor = dividir(50, 2)
valor = dividir(20, 2)

if valor < 18:
raise ValueError("Valor muito pequeno.")
else:
print(valor)

Saída:

valor = dividir(50, 2)
25.0

valor = dividir(20, 2)
ValueError: Valor muito pequeno.

Ao lançar a exceção, o programa para imediatamente a menos que você trate o erro com um try/except.



Captura genérica de erro


Você pode capturar qualquer exceção usando except sozinho, mas isso deve ser evitado, pois esconde o tipo de erro e dificulta o diagnóstico.

try:
x = 1 / 0
except:
print("Algo deu errado.")

O ideal é sempre capturar o tipo específico de exceção, como ZeroDivisionError, ValueError, TypeError, etc.



Captura com acesso ao erro


Você pode capturar o erro e ainda acessar a mensagem de exceção usando as:

try:
x = int("abc")
except ValueError as e:
print(f"Ocorreu um erro: {e}")

Saída:

Ocorreu um erro: invalid literal for int() with base 10: 'abc'


Mais sobre raise


Depois do raise você pode colocar qualquer objeto que seja uma exceção válida, ou seja, qualquer instância de uma classe que herda de BaseException, direta ou indiretamente. Geralmente, você usa classes de exceção que já existem no Python, como:

raise ValueError("Mensagem de erro")
raise TypeError("Tipo inválido")
raise ZeroDivisionError("Divisão por zero detectada")
raise RuntimeError("Algo deu errado")

Você também pode criar sua própria classe de exceção, desde que herde de Exception:

class MinhaExcecao(Exception):
pass

raise MinhaExcecao("Erro personalizado")


Você não pode colocar coisas como strings ou inteiros diretamente:

raise "erro"      # errado – string não é exceção
raise 404 # errado – inteiro não é exceção

Se tentar, Python dá TypeError: exceptions must derive from BaseException.



Raise para o try


Quando você faz um try, o Python observa toda a execução que ocorre dentro daquele bloco, incluindo funções que são chamadas dentro dele. Se qualquer exceção for lançada antes do try terminar, e essa exceção herdar de Exception, então o except Exception vai capturá-la normalmente.


Exemplo:

def verificar():
raise ValueError("Erro dentro da função")

try:
verificar()

except Exception as e:
print("Capturado:", e)

Saída:

Capturado: Erro dentro da função

Aqui, o raise está fora do try fisicamente, mas como ele é executado durante o try, a exceção é capturada.


Agora veja um contraexemplo, se o raise acontecer depois que o bloco try já terminou, ele não será capturado, mesmo que o try tenha chamado a função anteriormente.


Exemplo:

def verificar():
pass

try:
verificar()
except Exception:
print("Não será executado")

raise ValueError("Agora é tarde") # Aqui o raise ocorre fora do try

Isso não será capturado, e o programa termina com erro. Portanto, O raise só será capturado pelo except se acontecer durante a execução do try.



Listas


As listas em Python são coleções ordenadas e mutáveis que podem conter diversos tipos de valores. Elas são amplamente utilizadas para armazenar grandes quantidades de dados de forma organizada.


Embora listas em Python compartilhem algumas semelhanças com arrays em outras linguagens, como o Shell, elas são mais flexíveis, pois permitem armazenar diferentes tipos de dados e até mesmo outras listas, formando estruturas aninhadas. Isso torna as listas ideais para representar dados hierárquicos ou estruturados.

Em Python, o índice da primeira posição de uma lista é 0, ou seja, a contagem começa do zero.


ordenadas e mutáveis

Quando dizemos que listas são ordenadas, significa que os elementos nelas mantêm a mesma sequência em que foram adicionados. Se você cria uma lista com os valores [3, 1, 4], esses valores ficam armazenados exatamente nessa ordem, e você pode acessá-los por suas posições (índices). O primeiro elemento estará no índice 0, o segundo no índice 1 e assim por diante. A ordem importa e é preservada.


Ser mutável quer dizer que os elementos de uma lista podem ser modificados depois que ela é criada. Você pode alterar valores, adicionar novos elementos, remover itens e reorganizar a lista sem precisar criar uma nova. Por exemplo, se você tem a lista a = [10, 20, 30], pode fazer a[1] = 99 e o conteúdo da lista mudará para [10, 99, 30].


Essas duas características tornam as listas poderosas para armazenar e manipular conjuntos de dados dinâmicos.


Vejamos como trabalhar com listas de formas simples.

# Criando uma lista
lista1 = [1, 2, 3, 4]
lista2 = ['laranja', 'mamão', 'maçã', 'uva']

# Listando tudo que está na lista:
print("Lista 1:",lista1)
print("Lista 2:",lista2)
print()

# Listar posições específicas
print("Posição 3 da lista 1:",lista1[3]) # Lista a 3 posição, mostra o numero 4
print("Posição 2 da lista 2:",lista2[2]) # lista a segunda posição, exibe 'maçã'
print()

# Exibir a quantidade de itens da lista:
print("A lista 1 tem",len(lista1),"itens.")
print("A lista 2 tem",len(lista2),"itens.")

# Trocando valor do item da lista
lista2[1] = 'morango' # Troca mamão por morango

# Apagando uma posição:
del lista2[3] # Apaga UVA

#### Criando uma lista dentro de outra lista:
lista3 = [[1, 2, 3, 4],['laranja', 'mamão', 'maçã', 'uva']]

# Lista tudo da lista:
print("Lista 3:",lista3)
print()

# Listar posições específicas
print("Posição 3 da lista 1 que esta dentro da lista3:",lista3[1][3]) # Lista a 3 posição da lista 1, retorna UVA
print()

# Exibir a quantidade de itens da lista:
print("A lista 3 tem",len(lista3),"listas.")
print("A lista 3 posição 0 tem",len(lista3[0]),"itens.")
print("A lista 3 posição 1 tem",len(lista3[1]),"itens.")

##### SLICE #####
# [N:M]
# N = número começando em 0, é o ponto de partida;
# M = número começando em 1, é até onde deverá ser exibido.

# Imprimir usando um intervalo - slice
print(lista3[1][2:4]) # Imprimi o item 2 até 4 da lista 1 que estão dentro de lista3.

# Trocando valor do item da lista
lista3[1][1] = 'morango' - Troca mamão por morango

# Apagando uma posição
del lista2[1][3]


Método index()


Usado para mostrar qual a posição de um dado na lista:

lista = ['joao', 'rodrigo', 'azeitona', 'picles']

lista.index('azeitona')
# 2


Método append()


Usado para adicionr um item ao fim da lista:

# Adicionando no fim da lista

lista5 = ['joao', 'rodrigo']
lista6 = [['joao', 'rodrigo'], ['azeitona', 'picles']]

lista5.append('marcelo')
lista6[1].append('tomate')


Método insert()


Similar ao append(), mas aqui devemos fornecer a posição em que vamos add a informação. Se você escolher uma posição que já tenha um dado, ele não será apagado, mas sim deslocado para frente.

# Aqui escolhemos a posição em que vamos adicionar.

lista5.insert(0,'Fulano')


Método remove()


Similar ao método del, mas com remove() temos que fornecer a string que será apagada:

lista5.remove('Fulano')


Método pop()


Usado para remover o ultimo dado da lista:

lista = ['joao', 'rodrigo', 'azeitona', 'picles']
lista.pop()
# 'picles'

print(lista)
# ['joao', 'rodrigo', 'azeitona']

# Também podemos fornecer qual dado será removido (assim como del):
lista.pop(1)
# 'rodrigo'

print(lista)
# ['joao', 'azeitona']


Método count()


Retorna o número de vezes um dado aparece na lista:

lista = ['joao', 'rodrigo', 'joao', 'picles']

lista.count("joao")
# 2

# Com index, exibe apenas o primeiro match:
lista.index('joao')
# 0


Método reverse()


Inverte a posição dos elementos dentro da lista:

lista = ['joao', 'rodrigo', 'joao', 'picles']
lista.reverse()

print(lista)
# ['picles', 'joao', 'rodrigo', 'joao']


Método sort()


Usado para ordenar os dados dentro da lista:

lista5.sort()
lista6[0].sort()
lista6[1].sort()

# Ordena inversamente:
lista6[1].sort(reverse=True)

# Como o sort usa a tabela ASCII para ordenar,
# podemos ordenar de forma alfabética usando:
lista5.sort(key=str.lower)


Tuplas


Uma tupla é uma coleção ordenada como uma lista, mas é imutável. Ela é criada com parênteses () em vez de colchetes [], e seus valores não podem ser alterados, adicionados ou removidos após a criação. Isso as torna úteis para armazenar conjuntos de dados constantes e seguros.

lista_tupla = ('Hello', 1.5, 42, 'oi')

Tuplas são geralmente usadas quando você quer garantir que os dados não serão modificados acidentalmente. Por exemplo, quando uma função retorna múltiplos valores, ela os agrupa em uma tupla. Também são ideais para representar registros fixos, como coordenadas (x, y) ou datas (ano, mês, dia).


Por serem imutáveis, tuplas consomem menos memória e são ligeiramente mais rápidas do que listas em operações como iteração. Outra vantagem da imutabilidade é que tuplas podem ser usadas como chaves em dicionários e elementos de conjuntos (sets), o que listas não permitem.


Apesar de serem imutáveis, tuplas podem conter objetos mutáveis dentro delas. Por exemplo, uma tupla pode conter uma lista como um de seus elementos, e essa lista interna pode ser modificada.


Tuplas também suportam todas as operações básicas de sequência: indexação, fatiamento, iteração, e funções como len(), min(), max(), entre outras. Exemplo de uso:

ponto = (3, 4)
print(ponto[0]) # Acessa o primeiro elemento

Isso mostra que as tuplas são úteis, econômicas e seguras quando se deseja representar dados constantes e estruturados.



Iterável


Um iterável em Python é qualquer objeto que pode ser percorrido elemento por elemento em um loop, geralmente com a estrutura for. Ou seja, é um objeto que sabe fornecer seus itens um de cada vez.


Listas, tuplas, strings, dicionários, conjuntos e arquivos são exemplos de iteráveis. O Python usa um mecanismo chamado iterador para acessar os itens desses objetos. Quando você faz for item in colecao:, o Python está automaticamente pedindo ao objeto "iterável" que forneça um iterador, e então ele chama repetidamente esse iterador para obter os próximos elementos até acabar.


Você pode testar se algo é iterável usando a função iter() — se não der erro, é iterável:

iter([1, 2, 3])   # lista → iterável
iter("texto") # string → iterável
iter(10) # inteiro → não é iterável

Portanto, um iterável é qualquer estrutura de dados que pode ser lida item por item, tipicamente usada em loops.



TIME


O módulo time fornece várias funções para se trabalhar com o tempo (horas/minutos/dias).



SLEEP


Usado para fazer com que a execução do código espere X tempo antes de continuar:

import time

print("Esperando 5 segundos.")
time.sleep(5) # Espera 5 segundos
print("Pronto")


CTIME


Mostra a data baseado em segundos, desde 31 de Dezembro de 1969 as 21:00:00, isso se for usado os segundos como argumentos, se nao for usado, mostra a data/hora atual.

import time

print(time.ctime()) # Mostra a data/hora atual

# Exibindo quando 500 segundos após a data informada acima:
>>> print(time.ctime(500))
Wed Dec 31 21:08:20 1969