Estruturas de dados

As estruturas de dados são basicamente apenas isso - elas são estruturas que pode conter alguns dados. Em outras palavras, eles são usados para armazenar uma coleção de dados relacionados.

Existem quatro estruturas de dados incorporadas em Python - list, tuple, dictionary e set. Veremos como usar cada um deles e como eles tornam a vida mais fácil para nós.

List

Uma list é uma estrutura de dados que contém uma coleção ordenada de itens, ou seja, você pode armazenar uma sequencia de itens em uma lista. Isso é fácil de imaginar se você pode pensar em uma lista de compras onde você tem uma lista de itens para comprar, exceto que você provavelmente tem cada item em uma linha separada em sua lista de compras, enquanto em Python você colocou vírgulas entre eles.

A lista de itens deve ser entre colchetes para que Python entenda que você está especificando uma lista. Depois de criar uma lista, você pode adicionar, remover ou procurar itens na lista. Como podemos adicionar e remover itens, dizemos que uma lista é uma variavel tipo de dados, isto é, este tipo pode ser alterado.

Introdução rápida a objetos e aulas

Embora eu tenha geralmente atrasado a discussão de objetos e aulas até agora, é necessária uma pequena explicação neste momento para que você possa entender melhor as listas. Exploraremos este tópico em detalhes em um capítulo posterior.

Uma lista é um exemplo de uso de objetos e classes. Quando usamos uma variável i e atribua um valor a ele, diga inteiro 5 para isso, você pode pensar nisso como criando um objeto (isto é, instância) i de class (ou seja, tipo) int. Na verdade, você pode ler help(int) para entender melhor isso.

Uma classe também pode ter metodos ou seja, funções definidas para uso somente em relação a essa classe. Você pode usar essas peças de funcionalidade somente quando você tem um objeto dessa classe. Por exemplo, o Python fornece um append método para list classe que permite que você adicione um item ao final da lista. Por exemplo, mylist.append('an item') irá adicionar essa string à lista mylist. Observe o uso de notação pontilhada para acessar os métodos dos objetos.

Uma classe também pode ter campos que não são senão variáveis definidas para uso em relação a essa classe somente. Você pode usar essas variáveis / nomes somente quando você tem um objeto dessa classe. Os campos também são acessados pela notação pontilhada, por exemplo, mylist.field.

Exemplo (salvar como ds_using_list.py):

# This is my shopping list
shoplist = ['apple', 'mango', 'carrot', 'banana']

print('I have', len(shoplist), 'items to purchase.')

print('These items are:', end=' ')
for item in shoplist:
    print(item, end=' ')

print('\nI also have to buy rice.')
shoplist.append('rice')
print('My shopping list is now', shoplist)

print('I will sort my list now')
shoplist.sort()
print('Sorted shopping list is', shoplist)

print('The first item I will buy is', shoplist[0])
olditem = shoplist[0]
del shoplist[0]
print('I bought the', olditem)
print('My shopping list is now', shoplist)

Saida:

$ python ds_using_list.py
I have 4 items to purchase.
These items are: apple mango carrot banana
I also have to buy rice.
My shopping list is now ['apple', 'mango', 'carrot', 'banana', 'rice']
I will sort my list now
Sorted shopping list is ['apple', 'banana', 'carrot', 'mango', 'rice']
The first item I will buy is apple
I bought the apple
My shopping list is now ['banana', 'carrot', 'mango', 'rice']

Como funciona

A variável shoplist é uma lista de compras para alguém que está indo ao mercado. Na shoplist, Nós apenas armazenamos as strings dos nomes dos itens para comprar, mas você pode adicionar qualquer tipo de objeto para uma lista incluindo números e até outras listas.

Nós também usamos o for..in loop para iterar através dos itens da lista. Até agora, você deve ter percebido que uma lista também é uma seqüência. A especialidade das seqüências será discutida em uma seção posterior.

Observe o uso do end parâmetro na chamada para print função para indicar que queremos terminar a saída com um espaço em vez do intervalo de linha usual.

Em seguida, adicionamos um item à lista usando o append método do objeto da lista, como já discutido anteriormente. Então, verificamos se o item foi realmente adicionado à lista, imprimindo o conteúdo da lista simplesmente passando a lista para o print função que imprime de forma limpa.

Então, classificamos a lista usando o sort Método da lista. É importante entender que esse método afeta a lista em si e não retorna uma lista modificada - isso é diferente da maneira como as strings funcionam. É o que queremos dizer ao dizer que as listas são mutaveis e essas strings são imutaveis.

Em seguida, quando terminamos de comprar um item no mercado, queremos removê-lo da lista. Conseguimos isso usando o del declaração. Aqui, mencionamos qual item da lista queremos remover e o del A declaração remove-a da lista para nós. Nós especificamos que queremos remover o primeiro item da lista e, portanto, usamos del shoplist[0] (lembre-se de que o Python começa a contar de 0).

Se quiser conhecer todos os métodos definidos pelo objeto da lista, consulte help(list) para detalhes.

Tuple

Os Tuples são usados para conter vários objetos. Pense neles como semelhante às listas, mas sem a extensa funcionalidade que a classe da lista oferece. Uma das principais características das tuplas é que elas são imutaveis Como strings, você não pode modificar as tuplas.

Os Tuples são definidos especificando itens separados por vírgulas em um par de parênteses opcionais.

Os Tuples são geralmente utilizados nos casos em que uma declaração ou uma função definida pelo usuário pode assumir com segurança que a coleta de valores (ou seja, a tupla dos valores usados) não mudará.

Exemplo (salvar como ds_using_tuple.py):

# I would recommend always using parentheses
# to indicate start and end of tuple
# even though parentheses are optional.
# Explicit is better than implicit.
zoo = ('python', 'elephant', 'penguin')
print('Number of animals in the zoo is', len(zoo))

new_zoo = 'monkey', 'camel', zoo    # parentheses not required but are a good idea
print('Number of cages in the new zoo is', len(new_zoo))
print('All animals in new zoo are', new_zoo)
print('Animals brought from old zoo are', new_zoo[2])
print('Last animal brought from old zoo is', new_zoo[2][2])
print('Number of animals in the new zoo is',
      len(new_zoo)-1len(new_zoo[2]))

Saida:

$ python ds_using_tuple.py
Number of animals in the zoo is 3
Number of cages in the new zoo is 3
All animals in new zoo are ('monkey', 'camel', ('python', 'elephant', 'penguin'))
Animals brought from old zoo are ('python', 'elephant', 'penguin')
Last animal brought from old zoo is penguin
Number of animals in the new zoo is 5

Como funciona

A variável zoo refere-se a uma tupla de itens. Nós vemos que o len função pode ser usada para obter o comprimento da tupla. Isso também indica que uma tupla é uma sequencia também.

Agora estamos mudando esses animais para um novo zoológico desde que o antigo zoológico está sendo fechado. Portanto, o new_zoo tupla contém alguns animais que já estão lá, juntamente com os animais trazidos do antigo zoológico. De volta à realidade, note que uma tupla dentro de uma tupla não perde sua identidade.

Podemos acessar os itens na tupla, especificando a posição do item dentro de um par de colchetos, como fizemos para as listas. Isso é chamado de indexing operador. Acessamos o terceiro item em new_zoo especificando new_zoo[2] e acessamos o terceiro item no terceiro item no new_zoo tuple especificando new_zoo[2][2]. Isso é bastante simples uma vez que você entendeu o idioma.

Tuple com 0 ou 1 itens

Uma tupla vazia é construída por um par de parênteses vazios, como myempty = (). No entanto, uma tupla com um único item não é tão simples. Você precisa especificá-lo usando uma vírgula após o primeiro (e somente) item para que o Python possa diferenciar entre uma tupla e um par de parênteses em torno do objeto em uma expressão, ou seja, você precisa especificar singleton = (2 , ) Se você quer dizer que você quer uma tupla contendo o item 2.

Nota para programadores Perl

Uma lista dentro de uma lista não perde sua identidade, ou seja, as listas não são achatadas como em Perl. O mesmo se aplica a uma tupla dentro de uma tupla, ou uma tupla dentro de uma lista, ou uma lista dentro de uma tupla, etc. No que diz respeito ao Python, eles são apenas objetos armazenados usando outro objeto, isso é tudo.

Dicionário

Um dicionário é como um livro de endereços onde você pode encontrar o endereço ou os detalhes de contato de uma pessoa sabendo apenas o nome dele, ou seja, nós associamos keys (nome) com values (detalhes). Observe que a chave deve ser única, assim como você não pode descobrir as informações corretas se você tiver duas pessoas com o mesmo nome exato.

Observe que você pode usar apenas objetos imutáveis (como strings) para as chaves de um dicionário, mas você pode usar objetos imutáveis ou mutáveis para os valores do dicionário. Isto basicamente se traduz para dizer que você deve usar apenas objetos simples para chaves.

Pares de chaves e valores são especificados em um dicionário usando a notação d = {key1 : value1, key2 : value2 }. Observe que os pares de valores-chave são separados por dois pontos e os pares são separados por vírgulas e tudo isso está incluído em um par de chaves.

Lembre-se de que os pares de valores-chave em um dicionário não são ordenados de forma alguma. Se você quer um pedido específico, então você terá que classificá-los antes de usá-lo.

Os dicionários que você usará são instâncias / objetos do dict classe.

Exemplo (salvar como ds_using_dict.py):

# 'ab' is short for 'a'ddress'b'ook

ab = {
    'Swaroop': '[email protected]',
    'Larry': '[email protected]',
    'Matsumoto': '[email protected]',
    'Spammer': '[email protected]'
}

print("Swaroop's address is", ab['Swaroop'])

# Deleting a key-value pair
del ab['Spammer']

print('\nThere are {} contacts in the address-book\n'.format(len(ab)))

for name, address in ab.items():
    print('Contact {} at {}'.format(name, address))

# Adding a key-value pair
ab['Guido'] = '[email protected]'

if 'Guido' in ab:
    print("\nGuido's address is", ab['Guido'])

Saida:

$ python ds_using_dict.py
Swaroop's address is [email protected]

There are 3 contacts in the address-book

Contact Swaroop at [email protected]
Contact Matsumoto at [email protected]
Contact Larry at [email protected]

Guido's address is [email protected]

Como funciona

Criamos o dicionário ab usando a notação já discutida. Acrescamos os pares de valores-chave especificando a chave usando o operador de indexação como discutido no contexto de listas e tuplas. Observe a sintaxe simples.

Podemos excluir pares de valores-chave usando nosso antigo amigo - o del declaração. Nós simplesmente especificamos o dicionário e o operador de indexação para que a chave seja removida e passemos para a del declaração. Não há necessidade de conhecer o valor correspondente à chave para esta operação.

Em seguida, acessamos cada par chave-valor do dicionário usando o items método do dicionário que retorna uma lista de tuplas onde cada tupla contém um par de itens - a chave seguida pelo valor. Recuperamos esse par e atribuí-lo às variáveis name e address correspondentemente para cada par usando o for..in loop e, em seguida, imprima esses valores no for-block.

Podemos adicionar novos pares de valores-chave simplesmente usando o operador de indexação para acessar uma chave e atribuir esse valor, como fizemos para o Guido no caso acima.

Podemos verificar se existe um par chave-valor usando o in operador.

Para a lista de métodos do dict classe, veja help(dict).

Argumentos e Dicionários de Palavras-Chave

Se você usou argumentos de palavras-chave em suas funções, você já usou dicionários! Basta pensar nisso - o par chave-valor é especificado por você na lista de parâmetros da definição da função e quando você acessa variáveis dentro de sua função, é apenas um acesso de chave de um dicionário (chamado tabela de símbolos na terminologia do projeto compilador).

Seqüência

Listas, tuplas e strings são exemplos de seqüências, mas quais são as seqüências e o que é tão especial sobre elas?

As principais características são membership tests, (ou seja, o in e not in expressões) e operações de indexação, o que nos permite buscar um item específico na sequência diretamente.

Os três tipos de seqüências mencionadas acima - listas, tuplas e strings, também têm um fatiamento operação que nos permite recuperar uma fatia da sequência, isto é, uma parte da seqüência.

Exemplo (salvar como ds_seq.py):

shoplist = ['apple', 'mango', 'carrot', 'banana']
name = 'swaroop'

# Indexing or 'Subscription' operation #
print('Item 0 is', shoplist[0])
print('Item 1 is', shoplist[1])
print('Item 2 is', shoplist[2])
print('Item 3 is', shoplist[3])
print('Item -1 is', shoplist[-1])
print('Item -2 is', shoplist[-2])
print('Character 0 is', name[0])

# Slicing on a list #
print('Item 1 to 3 is', shoplist[1:3])
print('Item 2 to end is', shoplist[2:])
print('Item 1 to -1 is', shoplist[1:-1])
print('Item start to end is', shoplist[:])

# Slicing on a string #
print('characters 1 to 3 is', name[1:3])
print('characters 2 to end is', name[2:])
print('characters 1 to -1 is', name[1:-1])
print('characters start to end is', name[:])

Saida:

$ python ds_seq.py
Item 0 is apple
Item 1 is mango
Item 2 is carrot
Item 3 is banana
Item -1 is banana
Item -2 is carrot
Character 0 is s
Item 1 to 3 is ['mango', 'carrot']
Item 2 to end is ['carrot', 'banana']
Item 1 to -1 is ['mango', 'carrot']
Item start to end is ['apple', 'mango', 'carrot', 'banana']
characters 1 to 3 is wa
characters 2 to end is aroop
characters 1 to -1 is waroo
characters start to end is swaroop

Como funciona

Primeiro, vemos como usar índices para obter itens individuais de uma seqüência. Isso também é referido como o operação de subscrição. Sempre que você especificar um número para uma seqüência entre colchetes como mostrado acima, o Python irá buscar o item correspondente a essa posição na seqüência. Lembre-se de que o Python começa a contar números de 0. Portanto, shoplist[0] Obtém o primeiro item e shoplist[3] Obtém o quarto item no shoplistsequencia.

O índice também pode ser um número negativo, caso em que a posição é calculada a partir do final da seqüência. Assim sendo, shoplist[-1] refere-se ao último item na sequência e shoplist[-2] obtém o segundo último item na sequência.

A operação de corte é usada especificando o nome da seqüência seguida por um par opcional de números separados por dois pontos entre colchetes. Observe que isso é muito parecido com a operação de indexação que você já usou até agora. Lembre-se que os números são opcionais, mas o cólon não é.

O primeiro número (antes dos dois pontos) na operação de corte refere-se à posição a partir da qual a fatia começa e o segundo número (após o cólon) indica onde a fatia irá parar. Se o primeiro número não for especificado, o Python começará no início da seqüência. Se o segundo número for deixado de fora, Python irá parar no final da seqüência. Observe que a fatia retornou começos na posição inicial e terminará logo antes da posição fim ou seja, a posição de início está incluída, mas a posição final é excluída da fatia de seqüência.

Portanto, shoplist[1:3] retorna uma fatia da seqüência a partir da posição 1, inclui a posição 2, mas pára na posição 3 e, portanto, uma fatia de dois itens são devolvidos. similarmente, shoplist[:] retorna uma cópia de toda a seqüência.

Você também pode fazer cortes com posições negativas. Os números negativos são usados para posições do final da seqüência. Por exemplo, shoplist[:-1] retornará uma fatia da seqüência que exclui o último item da seqüência, mas contém o resto.

Você também pode fornecer um terceiro argumento para a fatia, que é o passo para o corte (por padrão, o tamanho do passo é 1):

>>> shoplist = ['apple', 'mango', 'carrot', 'banana']
>>> shoplist[::1]
['apple', 'mango', 'carrot', 'banana']
>>> shoplist[::2]
['apple', 'carrot']
>>> shoplist[::3]
['apple', 'banana']
>>> shoplist[::-1]
['banana', 'carrot', 'mango', 'apple']

Observe que quando o passo é 2, obtemos os itens com a posição 0, 2, ... Quando o tamanho do passo é 3, obtemos os itens com a posição 0, 3, etc.

Experimente várias combinações de tais especificações em fatia usando o intérprete Python de forma interativa, ou seja, o prompt para que você possa ver os resultados imediatamente. A grande coisa sobre as seqüências é que você pode acessar suas tuplas, listas e strings tudo da mesma maneira!

Definir

Os conjuntos são não ordenado coleções de objetos simples. Estes são usados quando a existência de um objeto em uma coleção é mais importante do que a ordem ou quantas vezes ocorre.

Usando conjuntos, você pode testar a adesão, se é um subconjunto de outro conjunto, encontrar a interseção entre dois conjuntos, e assim por diante.

>>> bri = set(['brazil', 'russia', 'india'])
>>> 'india' in bri
True
>>> 'usa' in bri
False
>>> bric = bri.copy()
>>> bric.add('china')
>>> bric.issuperset(bri)
True
>>> bri.remove('russia')
>>> bri & bric # OR bri.intersection(bric)
{'brazil', 'india'}

Como funciona

Se você se lembra da matemática da teoria de conjuntos básicos da escola, esse exemplo é bastante auto-explicativo. Mas, se não, você pode google "set theory" e "Venn diagram" entender melhor o nosso uso de conjuntos em Python.

Referências

Quando você cria um objeto e atribui-lo a uma variável, a variável apenas referem para o objeto e não representa o objeto em si! Ou seja, o nome da variável aponta para a parte da memória do seu computador onde o objeto está armazenado. Isso é chamado binding o nome para o objeto.

Geralmente, você não precisa se preocupar com isso, mas há um efeito sutil devido a referências que você precisa estar ciente de:

Exemplo (salvar como ds_reference.py):

print('Simple Assignment')
shoplist = ['apple', 'mango', 'carrot', 'banana']
# mylist is just another name pointing to the same object!
mylist = shoplist

# I purchased the first item, so I remove it from the list
del shoplist[0]

print('shoplist is', shoplist)
print('mylist is', mylist)
# Notice that both shoplist and mylist both print
# the same list without the 'apple' confirming that
# they point to the same object

print('Copy by making a full slice')
# Make a copy by doing a full slice
mylist = shoplist[:]
# Remove first item
del mylist[0]

print('shoplist is', shoplist)
print('mylist is', mylist)
# Notice that now the two lists are different

Saida:

$ python ds_reference.py
Simple Assignment
shoplist is ['mango', 'carrot', 'banana']
mylist is ['mango', 'carrot', 'banana']
Copy by making a full slice
shoplist is ['mango', 'carrot', 'banana']
mylist is ['carrot', 'banana']

Como funciona

A maioria das explicações está disponível nos comentários.

Lembre-se de que se você quiser fazer uma cópia de uma lista ou tais tipos de seqüências ou objetos complexos (não simples objetos como inteiros), então você precisa usar a operação de corte para fazer uma cópia. Se você simplesmente atribuir o nome da variável a outro nome, ambos "se referirão" ao mesmo objeto e isso poderá ser um problema se você não for cuidadoso.

Nota para programadores Perl

Lembre-se de que uma declaração de atribuição para listas não crie uma cópia. Você precisa usar a operação de corte para fazer uma cópia da seqüência.

Mais sobre strings

Nós já discutimos as strings em detalhes anteriormente. O que mais pode haver para saber? Bem, você sabia que as strings também são objetos e tem métodos que fazem tudo, desde verificar parte de uma seqüência de caracteres até espaçamentos? Na verdade, você já usou um método de string ... o método format!

As strings que você usa nos programas são todos objetos da classe str. Alguns métodos úteis desta classe são demonstrados no próximo exemplo. Para obter uma lista completa desses métodos, consulte help(str).

Exemplo (salvar como ds_str_methods.py):

# This is a string object
name = 'Swaroop'

if name.startswith('Swa'):
    print('Yes, the string starts with "Swa"')

if 'a' in name:
    print('Yes, it contains the string "a"')

if name.find('war') != -1:
    print('Yes, it contains the string "war"')

delimiter = '_*_'
mylist = ['Brazil', 'Russia', 'India', 'China']
print(delimiter.join(mylist))

Output:

$ python ds_str_methods.py
Yes, the string starts with "Swa"
Yes, it contains the string "a"
Yes, it contains the string "war"
Brazil_*_Russia_*_India_*_China

Como funciona

Aqui, vemos muitos dos métodos de string em ação. o startswith método é usado para descobrir se a seqüência de caracteres começa com a string fornecida. O in operador é usado para verificar se uma determinada string é uma parte da string.

O find método é usado para localizar a posição da substring dada dentro da string; find retorna -1 se não tiver êxito em encontrar a substring. o str classe também possui um método limpo para join os itens de uma seqüência com a seqüência que atua como um delimitador entre cada item da seqüência e retorna uma cadeia maior gerada a partir desta.

Resumo

Nós exploramos as várias estruturas de dados incorporadas de Python em detalhes. Essas estruturas de dados serão essenciais para a escrita de programas de tamanho razoável.

Agora que temos muitos dos fundamentos do Python no local, veremos a seguir como desenhar e escrever um programa Python do mundo real.