Cadeia de Caracteres
Manipulação de cadeia de caracteres
>>> s = 'Isso é uma cadeia de caracteres'
>>> s.split()
['Isso', '\xc3\xa9', 'uma', 'cadeia', 'de', 'caracteres']
>>> 'Isso' in s
True
>>> s.find('de')
14
>>> ', '.join(s.split())
'Isso, \xc3\xa9, uma, cadeia, de, caracteres'
A manipulação das cadeias de caracteres é a chave para a interpretação do conteúdo de arquivos.
- Texto em Python é representado pelas cadeias de caracteres;
- Inspecionar e manipular essas cadeias é o caminho para entender o conteúdo de arquivos;
- Plano: primeiro operações básicas, depois exemplos reais.
Um exemplo para ilustração:
>>> s = u'Berlim: 18.4 C\u2070 às 16h'
Veja mais
Veja mais códigos unicode para caracteres aqui
As cadeias de caracteres se comportam como tuplas (listas imutáveis):
>>> s[0]
'B'
>>> s[1]
'e'
>>> s[-1]
'h'
Extraindo partes de cadeia de caracteres
Partes de cadeias de caracteres podem ser obtidas da mesma forma que os cortes em listas:
>>> s
'Berlim: 18.4 C às 16h'
>>> s[8:] ## do indice 8 ao final da cadeia de caracteres
'18.4 C às 16h'
>>> s[8:12] ## indice 8, 9, 10 e 11 (não 12!)
'18.4'
>>> s[8:-1]
'18.4 C às 16'
>>> s[8:-8]
'18.4 C'
Achando o ínicio de um texto na cadeia de caracteres:
>>> s.find('Berlim') ## onde 'Berlim' inicia?
0 ## no indice 0
>>> s.find('h')
21
>>> s.find('Oslo') ## não encontrado
-1
Checando se um texto está contido em uma cadeia de caracteres
>>> 'Berlim' in s:
True
>>> 'Oslo' in s:
False
>>> if 'C' in s:
... print 'C achado'
... else:
... print 'nenhum C'
...
C achado
Substituindo um texto por outro
Sintaxe:
s.replace(s1, s2): substitui s1 por s2
>>> s.replace(' ', '__')
'Berlim:__18.4__C__às__4h'
>>> s.replace('Berlim', 'Curitiba')
'Curitiba: 18.4 C às 4h'
Exemplo: substituindo o texto antes dos dois pontos
>>> s
'Berlim: 18.4 C às 4h'
>>> s.replace(s[:s.find(':')], 'Curitiba')
'Curitiba: 18.4 C às 4h'
s.find(':')
retorna 6;s[:6]
é Berlim;- Berlim é substituido por Curitiba.
Dividindo uma cadeia de caracteres em uma lista de subtextos
s.split(arg)
divide em uma lista de subtextos separados pelo argumento arg. Exemplo:
>>> s
'Berlim: 18.4 C às 16h'
>>> s.split(':')
['Berlim', ' 18.4 C \xc3\xa0s 16h']
>>> s.split()
['Berlim:', '18.4', 'C', '\xc3\xa0s', '16h']
Tente endenter esse:
>>> s.split(':')[1].split()[0]
'18.4'
>>> deg = float(_) ## _ representa o último resultado no console
>>> deg
18.4
Dividindo uma cadeia de caracteres em linhas
Normalmente, os arquivos de dados contém muito texto e queremos separá-lo em linhas. Linhas podem ser separadas por diferentes caracteres de controle em diferentes plataformas:
\n
no Unix/Linux/Mac\r\n
no windows
>>> t = '1a linha\n2a linha\n3a linha' ## linha Unix
>>> print t
1a linha
2a linha
3a linha
>>> t.split('\n')
['1a linha', '2a linha', '3a linha']
>>> t.splitlines()
['1a linha', '2a linha', '3a linha']
>>> t = '1a linha\r\n2a linha\r\n3a linha' ## Windows
>>> t.split('\n')
['1a linha\r', '2a linha\r', '3a linha'] ## não é o resultado esperado!
>>> t.splitlines() ## qualquer plataforma!
['1a linha', '2a linha', '3a linha']
Cadeias de caracteres são objetos imutáveis
Não é possível modificar uma cadeia de caracteres (da mesma forma que as listas). Todas as modificações resultam em uma nova cadeia de caracteres.
>>> s[18] = 5
...
TypeError: 'str' object does not support item assignment
>>> ## criando uma nova cadeia de caracteres e adicionando partes de s:
>>> s2 = s[:19] + '5' + s[21:]
>>> s2
'Berlim: 18.4 C às 5h'
Removendo espaços em branco
>>> s = ' texto com espaços em branco antes e depois \n'
>>> s.strip()
'texto com espaços em branco antes e depois'
>>> s.lstrip() ## removendo da esquerda
'texto com espaços em branco antes e depois \n'
>>> s.rstrip() ## removendo da direita
' texto com espaços em branco antes e depois'
Algumas funções convenientes para cadeias de caracteres
>>> '214'.isdigit()
True
>>> ' 214 '.isdigit()
False
>>> '2.14'.isdigit()
False
>>> s.lower()
'berlim: 18.4 c às 4h'
>>> s.upper()
'BERLIM: 18.4 C ÀS 4H'
>>> s.startswith('Berlim')
True
>>> s.endswith('min')
False
>>> ' '.isspace() ## espaços em branco
True
>>> ' \n'.isspace() ## nova linha
True
>>> ' \t '.isspace() ## TAB
True
>>> ''.isspace() ## cadeia de caracteres vazia
False
Unindo cadeias de caracteres
Podemos unir uma lista de cadeias de caracteres para uma única cadeia:
>>> strings = ['Newton', 'Secante', 'Bisecção']
>>> ', '.join(strings)
'Newton, Secante, Bisecção'
As operações inversas seriam:
t = delimitador.join(listaCadeias)
listaCadeias = t.split(delimitador)
Eliminando as duas primeiras palavras em uma linha:
>>> linha = 'Esta é uma linha com palavras separadas por espaços'
>>> palavras = linha.split()
>>> linha2 = ' '.join(palavras[2:])
>>> print linha2
'uma linha com palavras separadas por espaços'
Lendo pares de números (x,y) de um arquivo
Arquivo de exemplo:
(1.3,0) (-1,2) (3,-1.5)
(0,1) (1,0) (1,1)
(0,-0.01) (10.5,-1) (2.5,-2.5)
Algoritmo:
- Leia linha por linha;
- Divida cada linha em palavras;
- Em cada palavra, remova o parênteses e divida o resto na vírgula.
O código:
linhas = open('ler_pares.dat', 'r').readlines()
pares = [] ## lista de (n1, n2) pares de números
for linha in linhas:
palavras = linha.split()
for palavra in palavras:
palavra = palavra[1:-1] ## removendo o parênteses
n1, n2 = palavra.split(',')
n1 = float(n1); n2 = float(n2)
par = (n1, n2)
pares.append(par)
Lista resultante em Python:
\[(1.3, 0.0),
(-1.0, 2.0),
(3.0, -1.5),
(0.0, 1.0),
(1.0, 0.0),
(1.0, 1.0),
(0.0, -0.01),
(10.5, -1.0),
(2.5, -2.5)\]
Solução alternativa: sintaxe Python no formato do arquivo
Suponha que o formato do arquivo
(1.3, 0) (-1, 2) (3, -1.5)
...
Seja um pouco diferente:
\[(1.3, 0), (-1, 2), (3, -1.5),
...
\]
Chamando a função eval
no formato diferente, é possível obter a lista final diretamente:
linhas = open('ler_pares.dat', 'r').readlines()
texto = open('ler_pares2.dat', 'r').read()
texto = '[' + texto.replace(')', '),') + ']'
pares = eval(texto)