Ditado e arquivo do Python

Tabela de hash de dicionário

A estrutura eficiente de tabela de hash de chave-valor de Python é chamada de "dict". O conteúdo de um dict pode ser escrito como uma série de pares de chave-valor dentro de chaves { }, por exemplo, dict = {key1:value1, key2:value2, ... }. O "dict vazio" é apenas um par vazio de chaves {}.

A pesquisa ou definição de um valor em um dict usa colchetes. Por exemplo, dict['foo'] procura o valor sob a chave "foo". Strings, números e tuplas funcionam como chaves, e qualquer tipo pode ser um valor. Outros tipos podem ou não funcionar corretamente como chaves (strings e tuplas funcionam perfeitamente, porque são imutáveis). Procurar um valor que não está no dict gera um KeyError. Use "in" para verificar se a chave está no dict, ou dict.get(key), que retorna o valor, ou None se a chave não estiver presente (ou get(key, não encontrado) permitirá que você especifique o valor a ser retornado no caso não encontrado).

  ## Can build up a dict by starting with the empty dict {}
  ## and storing key/value pairs into the dict like this:
  ## dict[key] = value-for-that-key
  dict = {}
  dict['a'] = 'alpha'
  dict['g'] = 'gamma'
  dict['o'] = 'omega'

  print(dict) ## {'a': 'alpha', 'o': 'omega', 'g': 'gamma'}

  print(dict['a'])     ## Simple lookup, returns 'alpha'
  dict['a'] = 6       ## Put new key/value into dict
  'a' in dict         ## True
  ## print(dict['z'])                  ## Throws KeyError
  if 'z' in dict: print(dict['z'])     ## Avoid KeyError
  print(dict.get('z'))  ## None (instead of KeyError)

dict com as teclas "a", "o" "g"

Uma repetição "for" em um dicionário itera nas chaves por padrão. As chaves aparecerão em ordem aleatória. Os métodos dict.keys() e dict.values() retornam listas de chaves ou valores explicitamente. Há também um items() que retorna uma lista de tuplas (chave, valor), que é a maneira mais eficiente de examinar todos os dados de chave-valor no dicionário. Todas essas listas podem ser passadas para a função classify().

  ## By default, iterating over a dict iterates over its keys.
  ## Note that the keys are in a random order.
  for key in dict:
    print(key)
  ## prints a g o

  ## Exactly the same as above
  for key in dict.keys():
    print(key)

  ## Get the .keys() list:
  print(dict.keys())  ## dict_keys(['a', 'o', 'g'])

  ## Likewise, there's a .values() list of values
  print(dict.values())  ## dict_values(['alpha', 'omega', 'gamma'])

  ## Common case -- loop over the keys in sorted order,
  ## accessing each key/value
  for key in sorted(dict.keys()):
    print(key, dict[key])

  ## .items() is the dict expressed as (key, value) tuples
  print(dict.items())  ##  dict_items([('a', 'alpha'), ('o', 'omega'), ('g', 'gamma')])

  ## This loop syntax accesses the whole dict by looping
  ## over the .items() tuple list, accessing one (key, value)
  ## pair on each iteration.
  for k, v in dict.items(): print(k, '>', v)
  ## a > alpha    o > omega     g > gamma

Nota estratégica: do ponto de vista do desempenho, o dicionário é uma de suas melhores ferramentas, e você deve usá-lo onde puder como uma maneira fácil de organizar os dados. Por exemplo, você pode ler um arquivo de registro em que cada linha começa com um endereço IP e armazenar os dados em um dict usando o endereço IP como chave e a lista de linhas em que ele aparece como o valor. Depois de ler o arquivo inteiro, você pode procurar qualquer endereço IP e ver instantaneamente sua lista de linhas. O dicionário recebe dados dispersos e os transforma em algo coerente.

Formatação de ditado

O operador % funciona convenientemente para substituir valores de um dict em uma string pelo nome:

  h = {}
  h['word'] = 'garfield'
  h['count'] = 42
  s = 'I want %(count)d copies of %(word)s' % h  # %d for int, %s for string
  # 'I want 42 copies of garfield'

  # You can also use str.format().
  s = 'I want {count:d} copies of {word}'.format(h)

Del

O operador "del" faz exclusões. No caso mais simples, ele pode remover a definição de uma variável, como se ela não tivesse sido definida. Ele também pode ser usado em elementos de lista ou frações para excluir essa parte da lista e entradas de um dicionário.

  var = 6
  del var  # var no more!

  list = ['a', 'b', 'c', 'd']
  del list[0]     ## Delete first element
  del list[-2:]   ## Delete last two elements
  print(list)      ## ['b']

  dict = {'a':1, 'b':2, 'c':3}
  del dict['b']   ## Delete 'b' entry
  print(dict)      ## {'a':1, 'c':3}

Arquivos

A função open() abre e retorna um identificador de arquivo que pode ser usado para ler ou gravar um arquivo da maneira habitual. O código f = open('name', 'r') abre o arquivo na variável f, está pronto para operações de leitura e usa f.close() quando termina. Em vez de "r", use "w" para escrever e "a" para anexar. O for-loop padrão funciona para arquivos de texto, iterando as linhas do arquivo (isso funciona apenas para arquivos de texto, não para arquivos binários). A técnica for-loop é uma maneira simples e eficiente de analisar todas as linhas em um arquivo de texto:

  # Echo the contents of a text file
  f = open('foo.txt', 'rt', encoding='utf-8')
  for line in f:   ## iterates over the lines of the file
    print(line, end='')    ## end='' so print does not add an end-of-line char
                           ## since 'line' already includes the end-of-line.
  f.close()

Ler uma linha de cada vez tem a boa qualidade de que nem todo o arquivo precisa caber na memória de uma só vez. Isso é útil se você quer visualizar todas as linhas de um arquivo de 10 gigabytes sem usar 10 gigabytes de memória. O método f.readlines() lê o arquivo inteiro na memória e retorna seu conteúdo como uma lista de linhas. O método f.read() lê o arquivo inteiro em uma única string, que pode ser uma maneira prática de lidar com todo o texto de uma vez, como acontece com expressões regulares que veremos mais tarde.

Para gravação, o método f.write(string) é a maneira mais fácil de gravar dados em um arquivo de saída aberto. Também é possível usar "print" com um arquivo aberto, como "print(string, file=f)".

Arquivos Unicode

Para ler e gravar arquivos codificados em Unicode, use um modo "t" e especifique explicitamente uma codificação:


with open('foo.txt', 'rt', encoding='utf-8') as f:
  for line in f:
    # here line is a *unicode* string

with open('write_test', encoding='utf-8', mode='wt') as f:
    f.write('\u20ACunicode\u20AC\n') #  €unicode€
    # AKA print('\u20ACunicode\u20AC', file=f)  ## which auto-adds end='\n'

Pratique o desenvolvimento incremental

Não escreva um programa completo em uma única etapa, apenas criando um programa em Python. Em vez disso, identifique apenas um primeiro marco, por exemplo, "a primeira etapa é extrair a lista de palavras". Escreva o código para chegar a esse marco e apenas mostre as estruturas de dados nesse ponto. Em seguida, é possível fazer um sys.exit(0) para que o programa não prossiga para as partes não concluídas. Quando o código do marco estiver funcionando, você poderá trabalhar no código para o próximo marco. Ser capaz de observar a exibição das variáveis em um estado pode ajudar você a pensar em como é preciso transformar essas variáveis para chegar ao próximo estado. O Python é muito rápido com esse padrão, permitindo que você faça algumas mudanças e execute o programa para ver como ele funciona. Aproveite esse rápido retorno para criar seu programa em etapas.

Exercício: wordcount.py

Combinando todo o material básico do Python, como strings, listas, dicts, tuplas, arquivos, faça o exercício de resumo wordcount.py nos Exercícios básicos.