Tabela haszująca dyktowania
W języku Python efektywna struktura tabeli haszującej pary klucz-wartość nosi nazwę „dict”. Treść żądania może być zapisywana w postaci serii par klucz:wartość w nawiasach klamrowych { }, np. dict = {klucz1:wartość1, klucz2:wartość2, ... }. „Puste dyktowanie” to po prostu pusta para nawiasów klamrowych {}.
Przy wyszukiwaniu lub ustawianiu wartości w słowniku są używane nawiasy kwadratowe, np. dict['foo'] wyszukuje wartość w kluczu „foo”. Ciągi, liczby i krotki działają jak klucze, a każdy ich typ może być wartością. 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 zapytaniu, zwraca błąd klucza – użyj operatora „in” aby sprawdzić, czy klucz znajduje się w dyktacie, lub użyj metody dict.get(key), która zwraca wartość, lub None (brak), jeśli klucz nie jest dostępny (lub get(key, not-found) pozwala określić, jaka wartość ma zostać zwrócona w przypadku nieznalezionego przypadku).
## 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)
Pętla for w słowniku domyślnie wykonuje iterację względem swoich kluczy. Klucze pojawią się w dowolnej kolejności. Metody dict.keys() i dict.values() zwracają listę 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: pod względem skuteczności słownik jest jednym z najlepszych narzędzi i należy go używać tam, gdzie może to ułatwić porządkowanie danych. Możesz na przykład odczytać plik dziennika, w którym każdy wiersz zaczyna się od adresu IP, i zapisać dane w dyktafonie, używając adresu IP jako klucza i listy wierszy, w których pojawia się on jako wartość. Po przejrzeniu całego pliku możesz wyszukać dowolny adres IP i od razu zobaczyć listę wszystkich wierszy. Słownik zbiera rozproszone dane, by uzyskać spójność.
Formatowanie dict
Operator % pozwala w wygodny sposób zastępować wartości z dyktowania w ciągu znaków 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
Parametr „del” przeprowadza usuwanie. W najprostszym przypadku funkcja może usunąć definicję zmiennej, tak jakby zmienna nie została zdefiniowana. Funkcji Del można też używać na elementach listy lub wycinkach, aby usuwać daną część listy i wpisy ze 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 się i zwraca uchwyt pliku, którego można użyć do odczytu lub zapisu pliku w zwykły sposób. Kod f = open('name', 'r') otwiera plik w zmiennej f, umożliwiając odczyt, a po zakończeniu służy funkcja f.close(). Zamiast „r” użyj „w”. do pisania oraz „a” w celu dołączenia. Standardowa pętla for działa w plikach tekstowych, powtarzając kolejne wiersze w pliku (działa to tylko w przypadku plików tekstowych, a nie binarnych). Metoda pętli „for” pozwala w prosty i wydajny sposób przyjrzeć się wszystkim wierszom 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()
Czytanie po jednym wierszu po kolei ma dobrą jakość, że nie wszystkie pliki muszą zmieścić się w pamięci jednocześnie, co jest przydatne, jeśli chcesz przyjrzeć się każdemu wierszowi w pliku 10 GB bez korzystania z 10 GB pamięci. Metoda f.readlines() odczytuje cały plik do pamięci i zwraca jego zawartość w postaci listy wierszy. Metoda f.read() odczytuje cały plik w postaci pojedynczego ciągu znaków, co może być przydatnym sposobem na jednoczesne zajmowanie się całym tekstem, jak w przypadku wyrażeń regularnych, które zobaczymy 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ć opcji „drukowanie” z otwartym plikiem, takim jak „print(string, file=f)”.
Pliki Unicode
Aby odczytywać i zapisywać pliki z kodowaniem Unicode, użyj trybu „nie” i jawnie 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'
Rozwój przyrostowy ćwiczeń
Podczas tworzenia programu w Pythonie nie pisz wszystkiego od razu. Zamiast tego określ tylko pierwszy etap, np. „Pierwszym krokiem jest wyodrębnienie listy słów.” Napisz kod, który pozwoli Ci osiągnąć ten etap, i wydrukuj wtedy struktury danych. Potem możesz zastosować sys.exit(0), by program nie zaprzątał sobie głowy niezrobionymi częściami. Gdy kod kamienia milowego będzie działać, możesz popracować nad nim dla kolejnego etapu. Możliwość zapoznania się z wydrukowanymi zmiennymi w jednym stanie może pomóc w zastanowieniu się, jak przekształcić te zmienne, aby przejść do kolejnego 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. Wykorzystaj ten krótki czas pracy, aby stworzyć swój program małymi krokami.
Ćwiczenie: wordcount.py
Łącząc wszystkie podstawowe materiały w języku Python – ciągi tekstowe, listy, słowniki, krotki i pliki – wypróbuj ćwiczenie podsumowujące wordcount.py w Ćwiczeniach podstawowych.