Struktura danych- słownik, lista, krotka- zajęcia 4

Dlaczego struktura danych jest ważna?

Wybór odpowiedniej struktury danych to podstawa!
Sposób przechowywania ma za zadanie sugerować odbiorcy w jaki sposób obsługiwać zawartość.
🗃️Różne pojemniki, mają różne cele przechowywania - np. skrzynka🔧 na narzędzia jest na narzędzia a nie np. na kawę ☕.

❓Podstawowe pytanie przed wyborem naszego "pojemnika", w którym będziemy przechowywać dane, to pytanie co ma robić nasza aplikacja.
Przy rozpoczynaniu projektu warto zadać sobie ogólne pytania, jaki mamy plan na aplikacje- co ma robić np. potrzebujemy miejsca na wyświetlanie wyniku, potrzebujemy listy uczestników, potrzebujemy móc poruszać się po danych, potrzebujemy niezmiennej listy danych. Dopiero kiedy przemyślimy jakich działań potrzebujemy, możemy zacząć dobierać nasze narzędzia które będą nam przydatne.

❓Pytania które warto sobie zadać przed wyborem struktury danych

  • Co ma robić nasz program
  • czy potrzebne nam uporządkowane dane
  • Czy dane mają być edytowalne
  • Czy dane się powtarzają
  • czy musimy usunąć powtarzające się dane
  • Jak duże będą dane
  • czy potrzebujemy szybkiego dostępu do danych

LISTA

Lista to uporządkowany, zmienny (modyfikowalny) typ danych, który służy do przechowywania kolekcji elementów. Listy są definiowane za pomocą nawiasów kwadratowych []. a ich elementy oddzielamy przecinkami. mogą zawierać elementy różnych typów w tym inne listy- dzięki czemu możemy tworzyć listy zagnieżdżone.

Podstawowe cechy list:
-uporządkowane- kolejność w listach ma znaczenie
-zmienne (modyfikowalne)
-Indexowane
-różnorodne typy
-Wartości na niej mają swoją kolejność
-listy mogą sie zmieniać (przeciwnie niż w krotkach)
-wartości mogą się powtarzać
-lista jest jak olbrzymia niekończąca się półka na której możemy ustawiać kolejne przedmioty

Tworzenie listy

Listy tworzymy poprzez kwadratowe nawiasy

zakupki=[jedzonko]
print(zakupki)

Aby stworzyć pełną listę, należy oddzielać poszczególne elementy przecinkami.

sprawunki=["jabłka", "brokuły", "makaron", "jogurt", "pomidory"]
print(sprawunki) #wydrukuje się zawartość listy

Na liście możemy umieszczać różnego rodzaju elementy, chociaż w praktyce najczęściej umieszcza się dane jednego typu

listunia=[1, "A", True, [], {a: "A"}]
print(listunia) #wydrukuje się zawartość nawiasu z zachowaniem właściwosci

Dodawanie elementu do listy - używamy metody append
nowy element "wskakuje" na pierwsze wolne miejsce- na koniec

fruits = ["Jabłko"]
print(fruits)  # ["Jabłko"]

fruits.append("Banan")
print(fruits)  # ["Jabłko", "Banan"]

fruits.append("Śliwka")
print(fruits)  # ["Jabłko", "Banan", "Śliwka"]

Aby "wyciągnąć" element z listy używamy metody pop. Metoda ta wyciąga ostatni element z listy jednocześnie usuwając go z niej.
WAŻNE! Nie usuwamy elementu z pustej listy bo prowadzi to do błędu przerywającego działanie programu

fruits = ["Jabłko", "Banan", "Śliwka"]
ret = fruits.pop()
print(ret)  # Śliwka
print(fruits)  # ["Jabłko", "Banan"]

Pusta lista i lista z elementami różnych typów/ lista z elementami tego samego typu

# pusta lista
lista_pusta = []

#lista z elementami różnych typów
lista_mieszana = [1, "tekst", 3.14, True, [1,2]]

lista z elementami tego samego typu
lista_liczb = [1, 2, 3, 4]

Łączenie dwóch list w jedną

Kiedy dodajemy do siebie dwie listy powstaje trzecia łącząca wszystko- należy pamiętać, że zmiana np. w liście 1 nie robi nam automatycznie zmian w liście 3 bo to już nowa niezależna lista.

list1 = [1, True]
list2 = ["A", []]
list3 = list1 + list2
print(list1)  # [1, True]
print(list2)  # ['A', []]
print(list3)  # [1, True, 'A', []]

list1[1] = False
print(list1)  # [1, False]
print(list3)  # [1, True, 'A', []]

Szukanie na liście

zakupy=["sól", "pieprz", "awokado", "halumi"]
print("chorizzo" in zakupy)
#wyjdzie False

Plugin black i rozbijanie kodu

Możemy instalować różne wtyczki i dodatki. Warto pomyśleć o przejrzystości kodu. Rozbicie kodu na wyraźne elementy pozwala łatwiej znaleźć w nim błędy ale też pomaga nam kiedy pracujemy z innymi osobami.

Rozbijanie dużej ilości elementów list/ krotki czy kodu zwiększa czytelność

punkty_doswiadczenia = [
100,
200,
765,
432,
128,
905
]

Funkcja len i mierzenie obiektów

Używamy funkcji len by "zmierzyć" ile obiektów ma np. nasza lista czy krotka

zakupy=["sól", "pieprz", "awokado", "halumi"]
print(len(zakupy))
#4

KROTKA

Krotka (ang. tuple) to uporządkowany, niezmienny (niemutowalny) zbiór elementów. Krotki są podobne do list, ale po utworzeniu nie można ich modyfikować. Tworzy się je za pomocą nawiasów okrągłych ().

Lepiej używać słowa tuple- krotka występuje na potrzeby kursów i książek, dobrze przestawiać się na łatwość operowania angielskimi nazwami.

Kiedy używamy krotek?
-kiedy chcemy mieć pewność, ze dane nie zostaną przypadkowo zmienione
-kiedy chcemy aby dane były niezmienne, np. jako klucze w słownikach
-kiedy chcemy aby kod był czytelniejszy i bardziej przejrzysty szczególnie przy zwracaniu wielu wartości z funkcji

Ważne
-krotki są niezmienne więc nie można dodawać ani usuwać ani zmieniać ich elementów po utworzeniu
Krotki są wydajniejsze niż listy gdy dane nie muszą być modyfikowalne
- krotki są iterowalne( można po nich literować za pomocą pętli)

  • Szybsze niż listy w wielu operacjach.
  • Zajmują mniej pamięci niż listy.
  • Mogą służyć jako klucze w słownikach.
  • Zapewniają bezpieczeństwo danych poprzez niezmienność.

Krotki są wszechstronnym i elastycznym narzędziem w Pythonie.

Krotki są podobne do listy- oddzielone przecinkami list wartości, nie trzeba stosować nawiasów ale wizualnie pomagają one odzielić je od reszty kodu.

#krotka bez nawiasu
t = 'a', 'b', 'c', 'd', 'e'

#krotka z nawiasami 
t = ('a', 'b', 'c', 'd', 'e')

#krotka pojedyncza
pojedyncza=(7,)

Krotki obsługujemy podobnie jak listy

zakupy=("sól", "pieprz", "awokado", "halumi")

print(len(zakupy))  # 4
print(zakupy[0])  # sól
print(zakupy[1:3])  # ("pieprz", "awokado")
print("chrorizo" in zakupy)  # False
print("awokado" in zakupy)  # True

Metody dostępne dla krotek

Tuple mają mniej dostępnych metod niż listy

.count() - zlicza ilość wystąpień przekazanych parametrów
.index()- podaje pierwszy indeks pod którym jest przekazana wartość
len - liczy ilość elementów
sum- sumuje wartość elementów krotki

Listy i krotki- porównanie

  • obie służą do przechowywania danych- jednej po drugiej w zorganizowany sposób
  • każdy element ma indeks co pozwala na szybkie znalezienie ale też "wyciągnięcie" tego czego potrzebujemy
  • obie mogą mieć duplikaty
  • w obu można przemieszczać się po ich elementach

ale!

listy:

  • listy są mutable- można dodawać/ odejmować nowe elementy (w krotkach nie)
  • W listach przemieszczamy się po ich elementach
  • unikamy sięgania po elementy w środku czy na końcu
  • ich analogią może być półka na książki
  • deklaruje się je przez nawiasy kwadratowe []
  • można dodać inne listy ale też krotki do nich
moje_ksiazki=["Blade Runner", "Hobbit", "Unicorn Projekt"]

Krotki (tuple)

  • krotki są niemodyfikowalne (immutable)
  • elementy w krotce są uporządkowane i mają niezmienną kolejność
  • częściej sięgamy po elementy głęboko w nich
  • analogią może być menu w restauracji
  • długość stała
  • nawiasy okrągłe ()
  • haszowalne
  • porównywalne- można sortować ich listy i używać jako kluczy w słownikach
  • Nie można modyfikować krotek- jeśli chcemy zmienić gotową krotkę musimy ją usunąć i zacząć od nowa
kategorie_menu=("przystawki", "zupy","dania glowne")

Indeksy

liczenie zaczynamy od 0- 0 jest na pierwszym miejscu.
Każdy element listy/krotki ma swój numer- tzw. indeks
chcąc "wyciągnąć" konkretny element wpisu identyfikator w nawiasach

nazwa_zmiennej[indeks]
mojaz_zmienna=["cos1", "cos2"]
print[moja lista]

wywoływanie po indeksie

fruits = ["Jabłko", "Banan", "Śliwka"]
print(fruits)  # ["Jabłko", "Banan", "Śliwka"]

print(fruits[1])  # Banan

print(fruits[0])  # Jabłko

print(fruits)  # ["Jabłko", "Banan", "Śliwka"]

fruit = fruits[2]
print(fruit)  # Śliwka

Cięcie list i krotek

Wykrawanie części
Możemy wyświetlić zakres listy/ krotki
Aby to zrobić musimy wpisać w nawiasie kwadratowym element startowy i element końcowy oddzielony dwukropkiem.

moja_zmienna[start:koniec]

przykład

lista_przyklad=["coś1", "coś2", "coś3", "coś4"]
krotka_przyklad=("coś1", "coś2", "coś3", "coś4")
print(lista_przyklad[1:3])
print(krotka_przyklad[1:3])
da nam wynik
['coś2, 'coś3']
('coś2, 'coś3')

Zatrzyma się przed ostatnim elemenetem- ostatni indeks nie będzie wypisany

Wybrane metody dla list i krotek

Metoda to specjalna funkcja przypisana do danego obiektu. Wywołuje się je po wpisaniu ich nazwy po kropce za nazwą obiektu.
Dalej tak jak w "normalnych" funkcjach -nawias okrągly i atrybuty

nazwa_zmiennej.nazwa_metody(atrybuty)

Do znalezienia różnych metod służą dymki podpowiedzi wyświetlane w programach


# .count() zlicza ilość wystąpień przekazanego parametru

my_list=[

# .index() podaje pierwszy indeks pod którym jest przekazana wartość
# .append()dodaje argument do listy
# .pop() usuń element o podanym indeksie z listy (lub ostatni element
# .sort() sortuje elementy
# .copy() zwraca kopię danych

SŁOWNIK

Słownik (ang. dictionary) to dynamiczna struktura danych, która przechowuje dane w postaci par klucz- wartość.
Klucze MUSZĄ BYĆ UNIKALNE I NIEZMIENNE (np. liczby, stringi), a wartości mogą być dowolnego typu.
Słowniki są odpowiednikiem tablic asocjacyjnych i pozwalają na efektywne wyszukiwanie, dodawanie i usuwanie elementów na podstawie kluczy.
szukamy zawartości z pomocą wartości klucza przypisanego do niej.
Jeśli wpiszemy ten sam klucz dwa razy- wartość zostanie nadpisana

TWORZENIE SŁOWNIKA

Słownik tworzy się za pomocą nawiasów klamrowych {}. Pary klucz- wartość oddzielone są dwukropkiem, a poszczególne pary przecinkami

slownik={'klucz1': 'wartosc1', 'klucz2'}
moj_slownik={klucz:wartość}

⚠️klucz musi być unikalny tzn.nie może powtórzyć się w słowniku. Wartości mogą być dowolne
⚠️klucz musi być wartością ma której da sie wykonać tzw. funkcję skrótu- podstawowe typy/ struktury "niemodyfikowalne mogą być kluczem- teksty, liczby krotki

Czyli:

🔑unikalny- nie może byc dwóch takich samych
🔑niemodyfikowalny- str| int|float|bool|tuple
🔑klucze muszą być zestawem takich samych elementów
📈wartość dowolna! str| dict|list|tuple czy funkcja- COKOLWIEK

moj_slownik = {'klucz1': 'wartosc1', 'klucz2': 'wartosc2'}
#klasyczny słownik


moj_slowniczek = {'key1': 'napis', 'key2': 123, 'key3': ['i1', 'i2', 'i3']} 
# słownik zawierający różne typy danych

☕Słownik - savoir vivre

Dobrą praktyką jest stosowanie jednorodnego schematu klucz:wartość
Jeśli np kluczem jest jakis tekst będący nazwą potrawy a wartością lista zawierająca jej składniki- trzymajmy się tego
Upewnijmy się, że faktycznie korzystamy w kodzie ze słownika- jeśli nie jest nam on potrzebny poszukajmy innej odpowiedniej struktury

pusty słownik

slownik_pusty={}

#Można utworzyć pusty slownik a dopiero potem dodawać do niego elementy

moj_slownik = {}                    
# utworzenie pustego słownika

moj_slownik['klucz1'] = 'wartosc1'  
moj_slownik['klucz2'] = 'wartosc2'
# dodanie klucz-wartość do słownika

🔧 Słownik obsługa


Aby wyświetlić wartość przechowywaną pod konkretnym kluczem, działamy podobnie jak z listami. Różnica taka, że w kwadratowych nawiasach nie podajemy indeksu a klucz 🔑
ważne! Do wersjy Pythona 3.7 struktura danych nieuporządkowana
Wartość kluczy musi być niemodyfikowalna

moj_slownik={"klucz1":"wartość1", "klucz2":"wartość2"}
print(moj slownik["klucz2])

dict1 = {'key1': 'napis', 'key2': 123, 'key3': ['i1', 'i2', 'i3']} # słownik zawierający różne typy danych

dict1['key3']    # wywołanie elementu słownika
#zwrot ['i1', 'i2', 'i3']

dict1['key3'][0] 
#odwołanie do zagnieżdżonego elementu słownika
#zwróci 'i1'

Wybrane metody dla słownika

.keys() - zwraca listę kluczy słownika
.values() - zwraca listę wartości słownika
.pop() - usuwa element o podanym kluczy
.items() zwraca listę krotek dla kazdej pary klucz:wartość
.get() zwraca wartość dla danego klucza

Zbiory (ang. set)

Zbiory wyglądają podobnie jak listy ale nie posiadają duplikatów wartości
Jeśli np. dwa razy spróbujemy do zbioru dodać słowo "kot" to ten drugi wpis zostanie usunięty
-nie mają indeksów
-można o nich myśleć jak o dziwnych słownikach, które mają jedynie klucze- tak jak słowniki deklaruje się je nawiasami klamrowymi.
-Ze względu na brak powtórzeń, często wykorzystuje się je np. zamieniając listę na zbiór aby pozbyć się duplikatów.
-Nie są uporządkowane więc dane mogą wyjść nam w innej kolejności
-Elementy zbioru muszą być hashowalne- czyli nie użyjemy listy czy słownika

moj_zbior={unikat1, unikat2, unikat3}
#zbiór utworzony za pomocą nawiasów klamrowych

zbiorek = set([1, 2, 2, 3, 4, 4, 5])  # Usunie duplikaty- to co się powtarza

#Dobrze to tłumaczy słowo ABRAKADABRA
zaklecie={‘A’,’B’,’R’,’A’,’K’,’A’,’D’,’A’,’B’,’R’,’A’}
print(zaklecie)
zaklecie=set([‘A’,’B’,’R’,’A’,’K’,’A’,’D’,’A’,’B’,’R’,’A’])
print(zaklecie)
zaklecie=set(‘ABRAKADABRA’)
print(zaklecie)
#po usunięciu wyjdzie :
{‘D’, ‘A’, ‘K’, ‘R’, ‘B’}
{‘D’, ‘K’, ‘R’, ‘A’, ‘B’}
{‘D’, ‘K’, ‘R’, ‘A’, ‘B’}

Pusty zbiór utworzymy tylko przy użyciu set

Poszczególne elementy zbioru nie są indeksowane. Możemy tylko sprawdzić czy dany element zbioru należy do niego czy nie. Używamy do tego in

zaklecie=set(‘czarymary’)
print(‘a’ in zaklecie)
#True
print(‘b’ in zaklecie)
#False
print(‘c’ not in zaklecie)
#False

Zbiory mają dostępne metody

"Metody add(x), remove(x), discard(x) dodają i usuwają element x ze zbioru. Metoda discard robi to warunkowo, pod warunkiem, że element x występuje w zbiorze. Nie wywołuje przez to błędu i nie przerywa programu w przeciwieństwie do metody remove."
Czyszczenie zbioru ze wszystkich elementów możemy wykonać za pomocą metody ‘clear’. Stosując metodę clear trzeba pamiętać, że trzeba wykonać zapasową kopię zbioru przed instrukcją zbior.clear(), a nie jednocześnie z nią."
Źródło cytatu i poniższych przykładów: https://skrypty.biol.uw.edu.pl/strona-glowna/python-dla-biologow/python-podstawowe-operacje/zbiory/


zbior=set([“a”,”b”,”c”])
zbior.add(“d”)
print(zbior)
zbior.remove(“a”)
print(zbior)
zbior.discard(“e”)
print(zbior)
zbior.remove(“e”)
# wyjdzie nam
{‘c’, ‘d’, ‘b’, ‘a’}
{‘c’, ‘d’, ‘b’}
{‘c’, ‘d’, ‘b’}
Traceback (most recent call last):
  File “C:\Users\User\OneDrive\Pulpit\A.py”, line 8, in <module>
zbior.remove(“e”)
KeyError: ‘e’


zbior=set(‘czarymary’)
print(zbior)
zbior1=zbior.clear()
print(zbior, zbior1)
>>>
{‘y’, ‘m’, ‘r’, ‘z’, ‘c’, ‘a’}
set() None

Inne przykładowe dostępne metody (jest ich więcej):

add(x) dodaje element x do zbioru
remove(x) usuwa element x ze zbioru, o ile się on tam znajduje. W przeciwnym wypadku generuje błąd.
discard(x) usuwa element x ze zbioru i nie daje błędu, gdy ten element w zbiorze się nie znajduje
pop()  usuwa element zbioru. Element wybierany jest losowo i po powtórzeniach operacji można uzyskać inny wynik.
issuperset sprawdza czy zbiór zawiera drugi zbiór. Zbiory sobie równe spełniają ten warunek
issubset sprawdza czy zbiór zawiera się w drugim zbiorze. Zbiory sobie równe spełniają ten warunek.

Obiekty modyfikowalne i niemodyfikowalne

Modyfikowalne:
liczby całkowite
liczby zmiennoprzecinkowe
wartości logiczne
ciągi znaków
krotki

niemodyfikowalne:
listy
słownik
zbiór

Polecane narzedzia do nauki szybkiego pisania
monkey type
tipp 10

Kamień papier nożyce

import random

wybor = ("papier", "nożyce", "kamień")

wybor_komputera = random.choice(wybor)
print(wybor_komputera)

idx_wybor_gracza = int(input("""
Wpisz nr odpowiadajacy Twojemu wyborowi:
0 - papier
1 - nozyce
2 - kamień
          """))

wybor_gracza = wybor[idx_wybor_gracza]

if wybor_komputera == "papier" and wybor_gracza=="nożyce":
print("Wygrana! Gratulacje")
elif wybor_komputera == "nożyce" and wybor_gracza=="kamień":
print("Wygrana! Gratulacje")
elif wybor_komputera == "kamień" and wybor_gracza=="papier":
print("Wygrana! Gratulacje")
else:
print("Przegrana :(!")

kwestionariusz- ZADANIE DOMOWE

import random

print("

punkty=0

kwestionariusz={

    "Czy popularna roślina monstera jest składnikiem napoju energetycznego
    Monster?":[
      ("tak", -0,5)
      ("nie", 1)
      ("tylko korzenie", -0,5)
    ],
    "Która z wymienionych roślin nazywana jest „chińskim lampionem”?:[
      ("epipremnium global green", -0,5)
      ("monstera veriagata", -0,5)
      ("ceropegia", 1)
    ],
    "Kiedy rośliny „tańczące” wykonują swój „taniec”?":[
      ("o zmierzchu", 1)
      ("kiedy słyszą muzykę", -0,5)
      ("w trakcie podlewania", -0,5)
    ],
    "Popularne określenie „bigos” w kontekście roślin dotyczy":[
      ("nawozu z odchodów dżdżownic kalifornijskich", -0,5)
      ("mieszanki podłoża składającego się np. z keramzytu, agroperlitu, czipsów kokosowych", 1)
      ("kompostownik z martwych roślin, nazwa pochodzi od powiedzenia niezły bigos", -0,5)
    ],
    "Seneccio Rowley nazywany jest sznurem pereł z powodu:"[
      ("liści w kształcie kulek, 1")
      ("perłowego koloru liśc", -0,5)
      ("rośliny tej używa się w przemyśle do wytwarzania pereł hodowlanych", -0,5)
    ],
    "Czy białe liście roślin pozbawione chlorofilu jak w Monsterze Veriagacie są w stanie fotosyntezować?":[
      ("nie", 1)
      ("tak ale tylko przy odpowiednim doświetlaniu", -0,5)
      ("tak ale tylko przy odpowiednim nawożeniu", -0,5)
    ],
    "Czy koty mogą spożywać rośliny egzotyczne?":[
      ("tak to dla nich bardzo korzystny sposób na oczyszczanie organizmu", -0,5)
      ("tak ale tylko po uprzednim ugotowaniu rośliny", -0,5)
      ("nie ponieważ egzotyczne rośliny mogą być dla nich zabójcze", 1)
    ],
    "Czy bananowce mogą być hodowane w gruncie w polskim klimacie??":[
      ("nie", -0,5)
      ("tak można hodować w gruncie dowolny gatunek bananowców", -0,5)
      ("można hodować tylko mrozoodporną odmianę", 1)
    ],
    "Czym jest paszport roślinny?":[
      ("to dokument wykonany z ekologicznych materiałów rodzimych roślin pozwalający na podróże w Europie", -0,5)
      ("to dokument, który wyrabia się dla roślin domowych jeśli chcemy z nimi podróżować po Polsce", -0,5)
      ("dokument wymagany przy sprzedaży roślin, niezbędny do handlu na odległość", 1)
    ],
    "Wełnowce to:":[
      ("wełniane ocieplacze dla roślin ogrodowych stosowane kiedy temperatura spada poniżej 10 stopni", -0,5)
      ("pasożyty", 1)
      ("dodatek stosowany do mieszanek gotowego podłoża, który zapewnia korzeniom dodatkowe poduszki powietrzne", -0,5)
    ]





#lista=["a", "b", "c"]
#random.shuffle(lista)
#print(lista)

Źródło: https://skrypty.biol.uw.edu.pl/strona-glowna/python-dla-biologow/python-podstawowe-operacje/zbiory/

Żrodło: https://www.learnpython.org/pl/Sets#google_vignette

Źródło: https://oprojektowaniu.pl/python-dla-inzynierow-slowniki/

Źródło: https://www.surowiecki.org/blog/flesz/python-krotki-niezmienne-sekwencje-danych/

Źródło: https://docs.python.org/pl/3/tutorial/datastructures.html

Źródło: https://kt.academy/pl/article/py-listy

#struktura danych
#krotka
#listy
#zbiory
#set
#tuple
#słownik
#dictionary
#metody