2.16. Sequências
Uma sequência é um conjunto ordenado de \(n\) valores:
\(a_0, a_1, a_2, ..., a_{n-1}\)
Cada elemento de uma sequência é associado a um número chamado de índice ou posição. O primeiro índice é o zero.
Os três tipos básicos de sequências são:
Strings: sequência imutável de caracteres.
Tuplas: sequência imutável de valores (ou itens).
Listas: sequência de valores (ou itens), que pode crescer, encolher, ou alterar elementos.
Operações comuns com sequências:
Operador |
Descrição |
---|---|
|
|
|
|
|
Concatenação de \(s\) e \(t\). |
|
\(i\)-th item de \(s\). |
|
Parte da sequência no intervalo \([i,j)\). |
|
Comprimento da sequência \(s\). |
|
Menor item da sequência \(s\). |
|
Maior item da sequência \(s\). |
|
Índice da primeira ocorrência de \(x\). |
|
Número total de ocorrências de \(x\) em \(s\). |
2.16.1. Strings
Como visto na Seção 2.14, strings são sequência imutáveis de caracteres:
>>> nome = "Introdução à Programação com Dados Geoespaciais"
>>> letra = "ç"
>>> if letra in nome:
... print(f"Nome contém a letra '{letra}'!")
... else:
... print(f"Nome não contém a letra '{letra}'!")
...
Nome contém a letra 'ç'!
>>> pos = nome.index(letra)
>>> print(pos)
>>> tamanho = len(nome)
>>> print(tamanho)
Nota
Para saber mais sobre strings, consulte a Seção 2.14.
2.16.2. Tuplas
As tuplas são expressas através de uma sequência cujos itens são separados por vírgula e delimitados ou não por parênteses. Vamos utilizar uma tupla para representar o par de coordenadas do centróide da cidade de São Paulo (Figura 2.19):
1centroide_sp = (-46.7165, -23.6830)
2
3print(centroide_sp)
4
5print("longitude: {} latitude: {}".format(*centroide_sp))
6
7print(len(centroide_sp))
8
9longitude = centroide_sp[0]
10latitude = centroide_sp[1]
No Trecho de Código 2.14 podemos observar o seguinte:
A
linha 01
cria uma tupla contendo dois valores em ponto flutuante e associa esse novo objeto ao nome (ou indentificador, ou variável)centroide_sp
.A
linha 05
utiliza uma notação especial para descompactar (unpack) a tupla na chamada do métodoformat
. Dessa maneira os valores individuais da tupla são passados ao métodoformat
, que poderá então usá-los no lugar das marcações de substituição (placeholders) da string de formatação.Na
linha 07
, usamos a funçãolen
, disponível para todos os tipos de sequência, para saber o número de elementos da tupla.As
linhas 09
e10
utilizam o operador de índice (operador[]
) para acessar os elementos da tupla. Repare que o primeiro elemento da tupla possui o índice0
.
Tuplas podem ser aninhadas (nested). No Trecho de Código 2.15, usamos uma tupla para representar o retângulo envolvente mínimo (REM ou Bounding Box) do polígono que define o limite (ou contorno, ou fronteira) da cidade de São Paulo (Figura 2.20). Veja que cada elemento da tupla, na linha 01
, é também uma tupla, com as coordenadas do canto inferior esquerdo e superior direito desse retângulo.
1rem_sp = ( (-46.8254, -24.0084), (-46.3648, -23.6830) )
2
3canto_inferior_esquerdo = rem_sp[0]
4
5canto_superior_direito = rem_sp[1]
6
7xmin = canto_inferior_esquerdo[0]
8
9ymin = rem_sp[0][1]
10
11print(f"xmax: {rem_sp[1][0]}")
No Trecho de Código 2.14 ainda temos:
Na
linha 03
, o operador de índice (operador[]
) é utilizado para acessar o primeiro par de coordenadas do retângulo envolvente. Podemos verificar que o elemento retornado por este operador também é uma tupla:>>> print(type(canto_inferior_esquerdo)) <class 'tuple'>
Na
linha 07
, utilizamos novamente o operador de índice ([]
) para acessar o valor de \(x_{min}\).A
linha 09
mostra que podemos usar o operador de índice de maneira encadeada, acessando o primeiro elemento da tupla mais externa e depois o valor do segundo elemento da tupla mais interna (\(y_{min}\)).A
linha 11
mostra como podemos usar elementos específicos da tupla dentro de uma string formatada.
Uma tupla é uma sequência imutável, isto é, se tentarmos alterar um item de uma tupla, uma exceção será lançada, como pode ser visto no trecho de código abaixo:
>>> centroide_sp[1] = 45.0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
2.16.3. Listas
As listas são expressas através de uma sequência cujos itens são separados por vírgula e delimitados por colchetes. Vamos criar uma lista com o nome de algumas cidades:
>>> cidades = [ "São Paulo", "Rio de Janeiro", "Belo Horizonte", "Ouro Preto"]
>>> print(cidades)
['São Paulo', 'Rio de Janeiro', 'Belo Horizonte', 'Ouro Preto']
Nota
Podemos distribuir os elementos de uma lista em múltiplas linhas. A lista cidades
, por exemplo, poderia ter sido definida da seguinte maneira:
>>> cidades = [
... "São Paulo",
... "Rio de Janeiro",
... "Belo Horizonte",
... "Ouro Preto"
... ]
Como uma lista é uma sequência mutável, existem operações que permitem modificar, por exemplo, a ordem de seus elementos. O método sort
permite ordenar os elementos de uma lista:
>>> cidades.sort()
>>> print(cidades)
['Belo Horizonte', 'Ouro Preto', 'Rio de Janeiro', 'São Paulo']
Nota
O método sort
não cria uma nova lista, ele realiza a alteração in-place. Para maiores informações sobre esse método, consulte [36].
Nota
Python oferece também uma função denominada sorted
que permite criar uma lista ordenada a partir de uma sequência qualquer. A definição dessa função pode ser encontrada em [18]. Para criar uma nova lista de cidades “ordenada ao contrário”, faça:
>>> nova_lista = sorted(cidades, reverse=True)
>>> print(nova_lista)
['São Paulo', 'Rio de Janeiro', 'Ouro Preto', 'Belo Horizonte']
Veja que a lista original (cidades
) continua com os elementos ordenados em ordem ascendente ou lexicográfica:
>>> print(cidades)
['Belo Horizonte', 'Ouro Preto', 'Rio de Janeiro', 'São Paulo']
Dica
Veja o seguinte tutorial sobre ordenação em Python [13].
Para adicionar um novo elemento ao final de uma lista, pode-se utilizar o método append
:
>>> cidades.append("São José dos Campos")
>>> print(cidades)
Para remover um elemento de uma posição específica de uma lista, utilizamos a operação del
junto com o opetrador de índice ([]
):
>>> del cidades[1]
>>> print(cidades)
['Belo Horizonte', 'Rio de Janeiro', 'São Paulo', 'São José dos Campos']
Para incluir os elementos de uma lista na outra, pode-se utilizar o método extend
:
>>> cidades.extend( ["Ouro Preto", "Mariana"] )
>>> print(cidades)
['Belo Horizonte', 'Rio de Janeiro', 'São Paulo', 'São José dos Campos', 'Ouro Preto', 'Mariana']
Para inverter a ordem dos elementos de uma lista, utilize o método reverse
:
>>> cidades.reverse()
>>> print(cidades)
['Mariana', 'Ouro Preto', 'São José dos Campos', 'São Paulo', 'Rio de Janeiro', 'Belo Horizonte']
Nota
Para uma lista completa das operações sobre sequências mutáveis, consulte [28].
2.16.3.1. Construindo Listas
As listas podem ser construídas de diversas formas:
Uma lista vazia, por exemplo, pode ser criada da seguinte maneira:
>>> lista_vazia = [] >>> print(lista_vazia) []
Uma lista pode ser criada a partir do construtor do tipo
list
, com uma sequência de valores:Lista vazia:
>>> list() []
Lista a partir de uma string:
>>> lista_letras = list("Introdução à Programação") >>> print(lista_letras) ['I', 'n', 't', 'r', 'o', 'd', 'u', 'ç', 'ã', 'o', ' ', 'à', ' ', 'P', 'r', 'o', 'g', 'r', 'a', 'm', 'a', 'ç', 'ã', 'o']
Lista a partir de uma tupla:
>>> primos = list((1, 2, 3, 5, 7)) >>> print(primos) [1, 2, 3, 5, 7]
Lista a partir de um range (iterável):
>>> lista_0_ate_9 = list(range(10)) >>> print(lista_0_ate_9) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2.16.3.2. List Comprehension
Uma maneira prática de construir listas é através da notação conhecida como list comprehensions. Esta notação, inspirada na linguagem funcional Haskell, apresenta a seguinte sintaxe básica:
[x for x in iterable]
Exemplos:
Lista com os números no intervalo de 0 a 9:
>>> lista = [ x for x in range(0, 10) ] >>> print(lista) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> type(lista) <class 'list'>
Lista dos quadrados:
>>> quadrados = [ x**2 for x in range(0, 10) ] >>> print(quadrados) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Suponha uma reta definida pela seguinte equação: \(y = 1.5 \times x - 3\). Dado os valores de \(x \in \{ 1, 2, 3, 4, 5 \}\), computar a lista de valores \(y\):
>>> xs = [ 1, 2, 3, 4, 5 ] >>> ys = [ (1.5 * x - 3) for x in xs ] >>> print(ys) [-1.5, 0.0, 1.5, 3.0, 4.5]
2.16.4. Generator Expressions
Outra notação concisa muito usada na linguagem Python é a de generator expressions. Muito parecida com a notação de list comprehensions, a sintaxe básica é a seguinte:
(x for x in iterable)
Diferentemente da notação de list comprehensions, que retorna uma lista, esta notação retorna um iterador ou gerador (generator):
>>> xs = [ 1, 2, 3, 4, 5 ]
>>> ys = ( (1.5 * x - 3) for x in xs )
>>> type(ys)
<class 'generator'>
ys
é tratado como um iterador, que gera os valores à medida do necessário:
>>> for y in ys:
... print(y)
...
-1.5
0.0
1.5
3.0
4.5
Esta estratégia evita que todos os elementos tenham que ser materializados de uma única vez. Repare que a grande diferença na notação é o uso de parênteses ((
e )
) no lugar de colchetes ([
e ]
).