Dyktowanie i plik w Pythonie

Tabela haszysmów słownika

Skuteczna struktura tabeli szyfrowania kluczy i wartości w Pythonie nazywana jest „słownikiem”. Treść zapytania można zapisać w postaci serii par klucz:wartość w nawiasach klamrowych { }, np. dict = {klucz1:wartość1, klucz2:wartość2, ... }. „Puste hasło” to pusta para nawiasów klamrowych {}.

Wyszukiwanie lub ustawianie wartości w słowniku odbywa się za pomocą nawiasów kwadratowych, np. dict['foo'] wyszukuje wartość pod kluczem „foo”. Jako klucze mogą służyć ciągi tekstowe, liczby i tuple, a wartością może być dowolny typ. Inne typy mogą, ale nie muszą, działać prawidłowo jako klucze (ciągi znaków i krotki działają poprawnie, ponieważ są stałe). Wyszukiwanie wartości, której nie ma w dyktacie, powoduje zgłoszenie błędu KeyError. Użyj operatora "in", aby sprawdzić, czy klucz znajduje się w dyktowaniu. Możesz też użyć funkcji dict.get(key), która zwraca wartość, lub None, jeśli klucz nie jest dostępny (lub get(key, not-found) pozwala określić, jaka wartość jest zwracana w przypadku nieznalezionego.

  ## 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)

słownik z kluczami „a”, „o”, „g”

Domyślnie pętla for na słowniku iteruje po jego kluczach. Klucze pojawią się w dowolnej kolejności. Metody dict.keys() i dict.values() zwracają listy kluczy lub wartości wprost. Dostępna jest też funkcja items(), która zwraca listę krotek (klucz, wartość). Jest to najskuteczniejszy sposób badania wszystkich danych par klucz-wartość w słowniku. Wszystkie te listy można przekazać do funkcji sort().

  ## 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

Uwaga dotycząca strategii: z perspektywy skuteczności słownik jest jednym z najlepszych narzędzi. Używaj go wszędzie tam, gdzie to możliwe, ponieważ ułatwia ono organizowanie danych. Możesz na przykład odczytać plik dziennika, w którym każdy wiersz zaczyna się od adresu IP, i zapisać dane w słowniku, używając adresu IP jako klucza, a listy wierszy, w których się on pojawia, jako wartości. Po przeczytaniu całego pliku możesz wyszukać dowolny adres IP i od razu zobaczyć listę zawartych w nim wierszy. Słownik przekształca rozproszone dane w coś spójnego.

Formatowanie w dyktandach

Operator % pozwala wygodnie zastępować wartości z słownika w ciągu według nazwy:

  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

Operator „del” służy do usuwania. W najprostszym przypadku funkcja może usunąć definicję zmiennej, tak jakby zmienna nie została zdefiniowana. Polecenie Del można też stosować do elementów listy lub wycinków, aby usunąć część listy i wpisy z słownika.

  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}

Pliki

Funkcja open() otwiera i zwraca uchwyt pliku, który można wykorzystać do odczytu lub zapisu pliku w zwykły sposób. Kod f = open('name', 'r') otwiera plik w zmiennej f, gotowy do operacji odczytu, a na koniec wywołuje f.close(). Zamiast „r” użyj „w” do zapisywania i „a” do dołączania. Standardowe pętle for działają w przypadku plików tekstowych, przechodząc przez linie w pliku (działa to tylko w przypadku plików tekstowych, a nie plików binarnych). Technika pętli for jest prostym i skutecznym sposobem na sprawdzenie wszystkich wierszy w pliku tekstowym:

  # 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()

Odczytywanie po jednym wierszu ma tę zaletę, że nie trzeba trzymać całego pliku w pamięci. Jest to przydatne, jeśli chcesz przejrzeć każdy wiersz 10-gigabajtowego pliku bez używania 10 gigabajtów pamięci. Metoda f.readlines() wczytuje cały plik do pamięci i zwraca jego zawartość jako listę wierszy. Metoda f.read() odczytuje cały plik w jednym ciągu znaków, co może być przydatnym sposobem na jednoczesne zajmowanie się całym tekstem, jak w przypadku wyrażeń regularnych, którymi popatrzymy później.

W przypadku zapisu metoda f.write(string) to najprostszy sposób zapisywania danych w otwartym pliku wyjściowym. Możesz też użyć polecenia „print” z otwartym plikiem, np. „print(string, file=f)”.

Pliki Unicode

Aby odczytywać i zapisywać pliki zakodowane w formacie Unicode, użyj trybu „t” i wyraźnie określ kodowanie:


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'

Ćwiczenie przyrostowego rozwoju

Podczas tworzenia programu w Pythonie nie pisz wszystkiego od razu. Zamiast tego określ pierwszy etap, np. „pierwszy krok to wyodrębnienie listy słów”. Napisz kod, który doprowadzi do tego etapu, i w tym momencie wydrukuj struktury danych. Następnie możesz użyć polecenia sys.exit(0), aby program nie przeszedł do nieukończonych części. Gdy kod etapu zacznie działać, możesz pracować nad kodem następnego etapu. Możliwość sprawdzenia wydruku zmiennych w danym stanie może pomóc Ci w zastanowieniu się, jak zmienić te zmienne, aby przejść do następnego stanu. Dzięki temu schematowi Python działa bardzo szybko, dzięki czemu można wprowadzić niewielką zmianę i uruchomić program, aby zobaczyć, jak działa. Skorzystaj z tej szybkiej metody, aby tworzyć program krok po kroku.

Ćwiczenie: wordcount.py

Połączenie wszystkich podstawowych elementów Pythona – ciągów znaków, list, słowników, krotek i plików – spróbuj wykonać podsumowanie ćwiczenia wordcount.py w sekcji Ćwiczenia podstawowe.