1.7. Słownik i obsługa plików

Informacja

W tym przykładzie zobaczysz, na czym polega zapis i odczyt plików tekstowych w różnych formatach, poznasz kolejną złożoną strukturę danych – słownik oraz nauczysz się wykonywać kolejne operacje na napisach.

1.7.1. Zadanie

Napisz program slownik.py, który pozwoli zapisywać w pliku tekstowym obce wyrazy oraz ich możliwe znaczenia. Program powinien pobierać dane z klawiatury w formacie: wyraz obcy: znaczenie1, znaczenie2, ... itd. Pobieranie danych kończy naciśnięcie klawisze ENTER. Podane dane powinny być zapisywane w pliku slownik.txt i/lub slownik.csv. Program powinien odczytywać wcześniej zapisane dane, a użytkownik powinien mieć możliwość dodawania nowych i zmieniania zapisanych danych.

Kod nr
 1import os  # moduł udostępniający funkcję isfile()
 2
 3slownik = {}  # pusty słownik
 4nazwa_pliku = 'slownik.txt'  # nazwa pliku zawierającego wyrazy i ich tłumaczenia
 5
 6
 7def otworz():
 8    if os.path.isfile(nazwa_pliku):  # czy istnieje plik słownika?
 9        with open(nazwa_pliku, 'r') as plik_txt:  # otwórz plik do odczytu
10            for wiersz in plik_txt:  # przeglądamy kolejne wiersze
11                # oczyszczamy wiersz ze znaków końca linii
12                # i rozbijamy na wyraz obcy i tłumaczenia
13                t = wiersz.strip().split(':')
14                # dodajemy do słownika wyraz obcy i listę znaczeń
15                slownik[t[0]] = t[1].split(',')
16    return len(slownik)  # zwracamy liczbę elementów słownika
17
18
19def zapisz():
20    # otwieramy plik do zapisu, istniejący plik zostanie nadpisany(!)
21    with open(nazwa_pliku, 'w') as plik_txt:
22        for w_obcy in slownik:
23            # 'sklejamy' znaczenia przecinkami w jeden napis
24            lista_znaczen = ','.join(slownik[w_obcy])
25            # wyraz_obcy:znaczenie1,znaczenie2,...
26            wiersz = ':'.join([w_obcy, lista_znaczen])
27            plik_txt.write(wiersz + '\n')  # zapisujemy w pliku kolejne wiersze
28            # można też tak: print(wiersz, file=plik_txt)
29
30
31def oczysc(tekst):
32    """Funkcja usuwa początkowe i końcowe białe znaki oraz znaki końca linii
33       i zwraca tekst zamieniony na małe litery"""
34    return tekst.strip().lower()
35
36
37def main(args):
38    print('''Wprowadzaj dane w formacie:
39    wyraz obcy: znaczenie1, znaczenie2
40    Aby zakończyć wprowadzanie danych, naciśnij ENTER.
41    ''')
42
43    # zmienna oznaczająca, że użytkownik uzupełnił lub zmienił słownik
44    czy_zastapic = False
45    czy_nowy = False
46    ile_wyrazow = otworz()
47    print('Słów w bazie:', ile_wyrazow)
48
49    # główna pętla programu
50    while True:
51        dane = input('Podaj wyraz obcy i jego znaczenia: ')
52        t = dane.split(':')
53        w_obcy = t[0].strip().lower()
54        if not w_obcy:
55            break
56        elif dane.count(':') == 1:  # sprawdzamy poprawność danych
57            if w_obcy in slownik:
58                print('Wyraz', w_obcy, ' i jego znaczenia są już w słowniku.')
59                czy_zastapic = input('Zastąpić wpis (t/n)? ')
60            # czy wyrazu nie ma w słowniku? a może chcemy go zastąpić?
61            if w_obcy not in slownik or czy_zastapic == 't':
62                znaczenia = t[1].split(',')  # znaczenia zapisujemy w liście
63                znaczenia = list(map(oczysc, znaczenia))  # oczyszczamy listę
64                slownik[w_obcy] = znaczenia
65                print(f'Dodano: {w_obcy}:{znaczenia}')
66                czy_nowy = True
67        else:
68            print('Błędny format!')
69
70    if czy_nowy:
71        zapisz()
72
73    print(slownik)
74
75    print('=' * 50)
76    print('{0: <15}{1: <40}'.format('Wyraz obcy', 'Znaczenia'))
77    print('=' * 50)
78    for w_obcy in slownik:
79        print('{0: <15}{1: <40}'.format(w_obcy, ','.join(slownik[w_obcy])))
80    return 0
81
82
83if __name__ == '__main__':
84    import sys
85    sys.exit(main(sys.argv))

1.7.1.1. Słownik

Słownik (zob. słownik) to struktura nieuporządkowanych danych w formacie klucz:wartość. Kluczami mogą być m.in. napisy i liczby, które wskazują na wartości dowolnego typu, np. inne napisy, liczby, listy, krotki itd. W programie wykorzystujemy słownik, którego kluczami są wyrazy obce, natomiast wartościami są listy możliwych znaczeń, np.:

slownik = {'go': ['iść', 'pojechać', 'chodzić'], 'look': ['patrzeć', 'poszukać'], 'see' : ['widzieć', 'zrozumieć']}

Operacje na słowniku:

  • slownik = {} – utworzenie pustego słownika,

  • slownik = { 'go':['iść','pojechać'] } – utworzenie 1-elementowego słownika,

  • slownik['make'] = ['robić','tworzyć'] – dodanie nowego elementu,

  • slownik['go'] – odczyt elementu wskazanego przez klucz.

1.7.1.2. Pliki tekstowe

Aby zilustrować niektóre operacje na napisach i listach, elementy słownika zapisywać będziemy do pliku w formacie wyraz_obcy:znaczenie1,znaczeni2,…. Funkcja otworz() przekształca format pliku na słownik, a funkcja zapisz() słownik na format pliku.

Operacje na plikach tekstowych:

  • os.path.isfile(plik) – zwraca prawdę, jeżeli podany plik istnieje,

  • open(plik, "w") – otwarcie pliku w podanym trybie: "r" – odczyt(domyślny), "w" – zapis, "a" – dopisywanie,

  • with open(nazwa_pliku) as plik: – otwarcie pliku w instrukcji with ... as ... zapewnia obsługę błędów, dba o zamknięcie pliku i udostępnia go w zmiennej plik,

  • for wiersz in plik: – plik tekstowy można rozumieć jako sekwencję wierszy, pętla for pozwala więc na odczyt kolejnych wierszy,

  • plik.write(tresc) – zapisuje do pliku podaną treść,

  • plik.close() – zamyka plik, ale lepiej używać konstrukcji z with.

Operacje na napisach:

  • .split(':') – dzieli tekst na części oddzielane podanym znakiem, zwraca je w postaci listy,

  • ','.join(lista) – łączy elementy listy podanym znakiem (w tym wypadku przecinkiem), zwraca tekst,

  • .lower() – zamienia znaki na małe litery,

  • .strip() – usuwa początkowe i końcowe białe znaki (spacje, tabulatory) oraz znaki końca wiersza,

  • .replace('co','czym') – zastępuje w ciągu wszystkie wystąpienia co – czym,

  • .count(znak) – zwraca liczbę wystąpień znaku w napisie.

W pętli głównej programu dane pobrane w formacie wyraz_obcy:znaczenie1,znaczeni2,… rozbijamy na wyraz obcy i jego znaczenia, które zapisujemy w liście t. Wszystkie elementy oczyszczamy, tj. zamieniamy na małe litery i usuwamy białe znaki. Funkcja map(oczysc, znaczenia) pozwala zastosować podaną jako pierwszy argument funkcję oczysc() do wszystkich elementów listy znaczenia podanej jako argument drugi. Instrukcja list() przekształca zwrócony przez funkcję map() obiekt z powrotem na listę.

1.7.1.3. Format csv

Dane tekstowe często zapisuje się w formacie csv. Jest to rozwiązanie wygodniejsze, ponieważ zwalnia nas od konieczności ręcznego przekształcania odczytywanych z pliku linii na struktury danych.

Na początku pliku dodajemy import modułu: import csv. Następnie zmieniamy nazwę pliku oraz funkcje otworz() i zapisz() na podane niżej:

Kod nr
 5nazwa_pliku = "slownik.csv"  # nazwa pliku zawierającego wyrazy i ich tłumaczenia
 6
 7
 8def otworz():
 9    if os.path.isfile(nazwa_pliku):  # czy istnieje plik słownika?
10        with open(nazwa_pliku, newline='') as plik_csv:  # otwórz plik do odczytu
11            tresc = csv.reader(plik_csv)
12            for wiersz in tresc:  # przeglądamy kolejne linie
13                slownik[wiersz[0]] = wiersz[1:]
14    return len(slownik)  # zwracamy liczbę elementów w słowniku
15
16
17def zapisz():
18    # otwieramy plik do zapisu, istniejący plik zostanie nadpisany(!)
19    with open(nazwa_pliku, "w", newline='') as plik_csv:
20        tresc = csv.writer(plik_csv)
21        for w_obcy in slownik:
22            lista = slownik[w_obcy]
23            lista.insert(0, w_obcy)
24            tresc.writerow(lista)

Format CSV polega na zapisywaniu wartości oddzielonych separatorem, czyli domyślnie przecinkiem. Jeżeli wartość zawiera znak separatora, jest cytowana domyślnie za pomocą cudzysłowu. W naszym wypadku przykładowa linia pliku przyjmie postać: wyraz obcy,znaczenie1,znaczenie2,...

Operacje na plikach CSV

  • csv.reader(plik) – metoda interpretuje podany plik jako format CSV i każdą linię zwraca w postaci listy elementów, wyodrębnionych za pomocą separatora,

  • csv.writer(plik) – metoda tworzy obiekt reprezentujący treść pliku w formacie CSV,

  • .writerow(lista) – metoda umożliwia zapis listy elementów w formacie CSV w obiekcie zwróconym przez metodę .writer().

Instrukcja slownik[linia[0]] = linia[1:] zapisuje dane w słowniku, kluczem jest wyraz obcy (1 element listy), wartościami lista znaczeń odczytana za pomocą notacji indeksowej.

1.7.2. Ćwiczenia

  1. Kod wypisujący słownik zamień na funkcję wypisz_slownik() i wykorzystaj ją do wypisywania słownika.

  2. Rozszerz program tak, aby umożliwiał usuwanie elementów słownika.

  3. Dodaj do programu możliwość uczenia się zapisanych w słowniku słówek, np. niech program wypisuje kolejne słowa obce i pobiera od użytkownika możliwe znaczenie i sprawdza, czy jest poprawne.


Licencja Creative Commons Materiały Python 101 udostępniane przez Centrum Edukacji Obywatelskiej na licencji Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0 Międzynarodowa.

Utworzony:

2026-05-30 o 19:12 w Sphinx 7.3.7

Autorzy:

Robert Bednarz