Python Iluminado

Strings

Introdução

Definição: Uma String é tradicionalmente um tipo de dados que representa uma sequência de caracteres.

Um caracter é simplesmente um símbolo. Por exemplo, o idioma inglês possui 26 caracteres.

Caracteres podem ser letras, dígitos, símbolos ($, !, #, @), etc.

Os computadores originalmente não lidam com caracteres, eles lidam fundamentalmente com números (binários). Mesmo que vejamos caracteres em nossa tela, internamente eles são armazenados e manipulados como uma combinação de 0's e 1's.

A conversão de caracteres em números é chamada de codificação e o processo reverso é a decodificação. ASCII e Unicode são algumas das codificações populares usadas. Em Python, uma string é uma sequência de caracteres Unicode. O Unicode foi introduzido para incluir todos os caracteres em todos os idiomas e trazer uniformidade na codificação.

A figura a seguir nos mostra a Tabela ASCII:

img

Com a função ord() podemos obter o valor ASCII para um determinado caracter:

ord('A') # 65
ord('X') # 88
ord('<') # 60

Contanto que permaneçamos no domínio dos caracteres comuns, haverá pouca diferença prática entre ASCII e Unicode. Mas a função ord() retornará valores numéricos para caracteres Unicode também:

ord('∑') # 8721
ord('火') # 28779

Já o método chr() faz o inverso de ord(). Fornecido um valor numérico, ele retorna uma string representando este valor.

chr(65) # 'A'
chr(88) # 'X'
chr(60) # '<'
chr(28779) # '火'

Existem diversos problemas no mundo real que envolvem as strings, podemos citar por exemplo:

  • Criptografia e Descriptografia
  • Análises de DNA
  • Tradução de linguagens

Fundamentos

Além dos números, Python é capaz de manipular strings com maestria, as strings podem ser expressas de diversas maneiras, podemos encapsular elas com aspas simples ('...') ou também aspas duplas ("...") ou até mesmo ("""...""") para múltiplas linhas. Por exemplo:

print('String é um elemento importante da programação')
print("Também podemos representá-las com aspas duplas")
print("""Podemos, até mesmo, representá-las com três aspas duplas, para textos grandes""")

Como podemos ver, strings podem ser impressas utilizando a função print() Caso você queira usar palavras entre aspas na sua string, você deve usar \ (contrabarra) para dar escape nas aspas, caso contrário ocorrerá um erro:

print("Podemos usar aspas dentro das \"strings\"")
print('Podemos usar aspas dentro das \'strings\'')

Ou até mesmo você pode inverter o uso das aspas:

print("Dessa forma não há 'problema'")
print('Dessa forma não há "problema"')

Índices de Strings

Assim como em diversas linguagens de programação, strings em Python são consideradas arrays de bytes que representam caractéres unicode, entretanto Python não tem um tipo de dados caracter. Caracteres únicos são simplesmente strings de tamanho 1. Para acessarmos elementos individuais das strings, utilizamos colchetes [].

img

s = "Rafael"
print(s[0]) # Imprime a primeira letra do nome
print(s[-6]) # Imprime a primeira letra do nome
print(s[5]) # Imprime a última letra do nome
print(s[-1]) # Imprime a última letra do nome

Observe que foi utilizado a notação s[0], isso porque o primeiro caracter começa na posição 0, lembre que isso é muito comum nas linguagens de programação e estruturas de dados. Cada caracter na string é associado com um índice numérico, que é um inteiro representando a localização do caracter em uma determinada string.

Além disso, podemos formar substrings a partir de uma string.

nome = "John Von Neumann"

Neste exemplo, selecionamos o caracter da posição 5 até 11 (não incluindo 12):

print(nome[5:12]) # Von Neu

Podemos também reverter a string usando a seguinte notação:

print(nome[::-1]) # nnamueN noV nhoJ

Métodos em Strings

Um detalhe importante dentro do universo das strings é que podemos utilizar métodos (funções especiais) para manipulalá-las.

Para compreendermos melhor estes métodos, vamos definir uma string para podermos testá-los:

nome = " Meu nome é Dennis Ritchie "

O método strip() remove todos os espaços extras no começo e no fim da string:

print(nome.strip()) # Meu nome é Dennis Ritchie

O método len() retorna o tamanho (comprimento) da string:

print(len(nome)) # 27

O método lower() retorna a string em lower case (todos os caracteres se tornam minúsculos):

print(nome.lower()) # meu nome é dennis ritchie

O método upper() retorna a string em upper case (todos os caracteres se tornam maiúsculos):

print(nome.upper()) # MEU NOME É DENNIS RITCHIE

O método swapcase() retorna a string com caracteres uppercase convertidos para lowercase e vice-versa:

print(nome.swapcase()) # mEU NOME É dENNIS rITCHIE

O método title() retorna a string ao qual a primeira letra de cada palavra é convertida para uppercase e as demais letras pernanecem lowercase:

print(nome.title()) # Meu Nome É Dennis Ritchie

O método replace() substitui a string que desejarmos por outra string especifica por nós via argumento:

  • Primeiro informamos a string a ser substituída
  • Segundo informados a nova string
print(nome.replace("Dennis", "Ken")) # Meu nome é Ken Ritchie

O método split() separa a string em substrings caso haja um separador, nesse caso utilizamos o espaço (" ") e ele nos retorna uma lista de strings:

print(nome.split(" ")) # ['', 'Meu', 'nome', 'é', 'Dennis', 'Ritchie', '']

O método join() retorna a string que resulta da concatenação dos objetos em um iterável separados por delimitador.

No exemplo a seguir, o delimitador é a string ',' e o iterável é uma lista de filósofos:

filosofos = ['Kant', 'Kierkegaard', 'Nietzsche', 'Leibniz']
print(', '.join(filosofos)) # Kant, Kierkegaard, Nietzsche, Leibniz
print(' - '.join(filosofos)) # Kant - Kierkegaard - Nietzsche - Leibniz

O resultado é uma única string que consiste nos objetos da lista separados por um delimitador especificado por nós.

No próximo exemplo, iterável é especificado como um único valor de string. Quando um valor de string é usado como um iterável, ele é interpretado como uma lista dos caracteres individuais da string:

list('aeiou') # ['a', 'e', 'i', 'o', 'u']
'|'.join('aeiou') # 'a|e|i|o|u'

O método count() retorna o número de ocorrências não sobrepostas de substring informada por nós:

print("Ra Ra Ja Ra Ta".count("Ra")) # 3

O método startwith() retorna True se uma determinada string começa com um prefixo especificado, caso contrário, retorna False:

print("existencialismo".startswith("exist")) # True
print("existencialismo".startswith("ismo")) # False

O método endswith() retorna True se uma determinada string termina com um sufixo especificado, caso contrário, retorna False:

print("existencialismo".endswith("ismo")) # True
print("existencialismo".endswith("exist")) # False

O método find() pode ser usado para vermos se uma string contém uma substring informada e retorna o menor índice na string onde esta substring é encontrada:

print('Amar, é encontrar a própria felicidade na felicidade alheia'.find('Amar')) # 0
print('Amar, é encontrar a própria felicidade na felicidade alheia'.find('é')) # 6

Os métodos de classificação de caracteres são capazes de classificar uma string baseado nos caracteres contidos nela. Vejamos alguns exemplos.

O método isalnum() retorna True se a string for não-vazia e todos os seus caracteres forem alfanuméricos (ou uma letra ou um número), e caso contrário, retorna False.

print('xyz678'.isalnum()) # True
print('xyz#678'.isalnum()) # False
print(' '.isalnum()) # False

O método isalpha() retorna True se a string for não-vazia e todos os seus caracteres forem alfabéticos, caso contrário, retorna False.

print('exemplo'.isalpha()) # True
print('exemplo 2'.isalpha()) # False

Para checarmos se uma string contém apenas dígitos, podemos utilizar o método isdigit(), ele vai retornar True se a string for não-vazia e todos os caracteres forem numéricos, e caso contrário, retornará False.

print('33'.isdigit()) # True
print('a33z'.isdigit()) # False
print(''.isdigit()) # False

O método isidentifier() nos retorna True se uma determina string é um identificador válido de acordo com a definição da linguagem Python, caso contrário, retorna False.

print('nome'.isidentifier()) # True
print('nome2'.isidentifier()) # True
print('2nome'.isidentifier()) # False
print('nome#'.isidentifier()) # False

Dessa forma podemos saber como definir uma variável corretamente.

Já o método iskeyword() é capaz de testar se uma determinada string corresponde à uma palavra-chave Python, este método é contido no módulo keyword, sendo então necessário importá-lo.

from keyword import iskeyword
print(iskeyword("or")) # True
print(iskeyword("else")) # True
print(iskeyword("while")) # True
print(iskeyword("switch")) # False

O método isprintable() determina se uma string consiste inteiramente de caracteres imprimíveis. Ele retorna True se a string for vazia ou se todos os caracteres alfabéticos que ela conter forem imprimíveis, retorna False se ela conter pelo menos um caracter não-imprimível. Caracteres não-alfabéticos são ignorados.

print('Gabriel\tFelippe'.isprintable()) # False
print('Gabriel Felippe'.isprintable()) # True
print(''.isprintable()) # True
print('x\ny'.isprintable()) # False

O método isspace() determina se uma string consiste de caracteres de espaço em branco, retornará True se a string for não-vazia e todos os caracteres forem de espaço em branco, caso contrário, retornará False.

print(''.isspace()) # False
print('x'.isspace()) # False
print(' '.isspace()) # True
print('\t\n'.isspace()) # True

O método isupper() é capaz de verificar se todos os caracteres de uma string são uppercase:

print("STRING".isupper()) # True
print("String".isupper()) # False

Já o método islower() é capaz de identificar se todos os caracteres de uma string são lowercase:

print("String".islower()) # False
print("string".islower()) # True

Formatando Strings

Vejamos agora como podemos usar métodos que modificam ou aprimoram o formato de uma string.

O método center() retorna uma string centralizada em um determinado comprimento especificado por nós via argumento, por padrão, o preenchimento consiste no caractere de espaço ASCII, por exemplo:

'python'.center(20) # ' python '
'python'.center(25,'.') # '..........python.........'

O método expandtabs() substitui cada caracter tab (\t) com espaços.

'x\ty'.expandtabs() # 'x y'

O método ljust() retorna uma string justificada à esquerda em um campo de comprimento especifica por nós via argumento, por padrão, o preenchimento consiste no caractere de espaço ASCII, por exemplo:

'C++'.ljust(10) # 'C++ '
'C++'.ljust(10,'-') # 'C++-------'

O método rjust() retorna uma string justificada à direita em um campo de comprimento especifica por nós via argumento, por padrão, o preenchimento consiste no caractere de espaço ASCII, por exemplo:

'Javascript'.rjust(20) # ' Javascript'
'Javascript'.rjust(20,'-') # '----------Javascript'

O método zfill() retorna uma cópia da string com preenchimento à esquerda com caracteres '0', o comprimento é especificado por nós, por exemplo:

'66'.zfill(4) # '0066'

Embora seja mais interessante para números, zfill() também funciona com caracteres:

'letra'.zfill(7) # '00letra'

O método format() nos permite construir strings de uma maneira flexível:

nome = "Rafael"
profissao = "Programador"
print("A profissão de {0} é {1}".format(nome,profissao))
# A profissao de Rafael é Programador

Criando um elemento HTML:

tag = 'p'
texto = 'Este é um parágrafo'
sentenca = '<{0}>{1}</{0}>'.format(tag, texto)
print(sentenca) # <p>Este é um parágrafo</p>

Calculando um valor:

valor = '1 GB é igual a {:,} bytes'.format(10**9)
print(valor) # 1 GB é igual a 1,000,000,000 bytes

Existe também a possibilidade de usarmos Códigos de Formatação.

Inteiro:

print("{:d}".format(4)) # 4

Binário:

print("{:b}".format(55)) # 110111

Hexadecimal:

print("{:x}".format(15)) # f

Lista:

print("{:}".format([20, 30])) # [20, 30]

Também podemos representar as strings de maneira similar ao estilo da linguagem C.

String:

nome = "Alan"
amigo = "Jones"
print("%s é amigo de %s" %(nome,amigo))
# Alan é amigo de Jones

Inteiro:

print("%d" % (4545)) # 4545

Float:

print("%3.5f" % (3.123456789)) # 3.12346
print("%2.4f" % (3.123456789)) # 3.1235

F-Strings

F-strings são um novo tipo de string literals introduzido na versão 3.6 do Python. A string formatada é prefixada com a letra f e é similar à formatação de strings aceita por format().

Vejamos exemplos:

first_name = "Alan"
last_name = "Turing"
sentenca = f'Meu nome e {first_name.upper()} {last_name.lower()}'
print(sentenca) # Meu nome e ALAN turing

Observe que podemos também executar métodos com F-strings.

Além disso, podemos também utilizar dicionários:

pessoa = {'nome': 'Muhammad', 'idade': 22}
sentenca = f'Meu nome é {pessoa["nome"]} e eu tenho {pessoa["idade"]} anos de idade'
print(sentenca)
# Meu nome é Muhammad e eu tenho 22 anos de idade

Ou até mesmo realizar operações matemáticas:

calculo = f'4 vezes 11 é igual a {4 * 11}'
print(calculo) # 4 vezes 11 é igual a 44
for n in range(1,11):
sentenca = f'O Valor é {n:02}'
print(sentenca)

Para formatarmos datas precisaremos importar a biblioteca datetime:

from datetime import datetime
nascimento = datetime(1991, 6, 6)
sentenca = f'O Nascimento é no dia {nascimento:%B %d, %Y}'
print(sentenca)
# O Nascimento é no dia June 06, 1991

Convertendo para o Formato String

Para fazermos a conversão para uma string podemos utilizar os métodos repr() e str():

x = 10
y = [1, 3.14, 17, 13]
print(type(repr(x))) # <class 'str'>
print(type(str(y))) # <class 'str'>

Escape Caracteres

Strings também são capazes de aceitar Escape caracteres:

CarácterDescrição
\nnova linha
\rcarriage return
\sespaço
\ttab
\vtab vertical
\eescape
\bbackspace

Vejamos um exemplos dos escape caracteres:

print("Meu nome é\nGabriel")
print("\tOlá meu amigo")

Operadores

Operadores Especiais:

OperadorDescrição
+concatenação, adiciona os valores
*repetição, concatena múltiplas cópias da mesma string
inpara verificarmos se determinado caracter existe na string
not inpara verificarmos se determinado caracter não existe na string

Veja um exemplo dos operadores especiais:

nome = "Carl"
sobrenome = "Sagan"
print(nome +" "+ sobrenome) # Concatena o nome e sobrenome
print(nome*10) # Multiplica o nome por 10
print("C" in nome) # Verifica se C está presente em nome e retorna True
print("C" not in nome) # Verifica se C não está presente em nome e retorna False

É importante lembrarmos que strings são imutáveis, uma vez criada, não pode ser modificada. Para alterar uma string você deve primeiro construir uma nova string através da concatenação ou chamada de uma função e então re-atribuir à variável string.

O conteúdo de strings é bastante extenso e continuaremos vendo elas ao longo do guia, considere dar bastante importância a elas!