Warning
This page is located in archive. Go to the latest version of this course pages. Go the latest version of this page.

4. Složené datové typy

Přehled datových typů dostupných v základní instalaci Pythonu

Základní:

  • int: Celé číslo (integer)
  • float: Desetinné číslo
  • str: Textový řetězec (string)
  • bool: Binární logická hodnota
  • complex: Komplexní číslo
  • bytes: Binární hodnota (nereprezentovaná)

Složené:

  • list: Seznam
  • tuple: N-tice
  • range: Rovnoměrná posloupnost
  • set, frozenset: Množina
  • str: Textový retězec (string)
  • dict: Slovník
  • bytearray: Pole binárních hodnot
  • memoryview: Binární obraz

Seznam: list

Seznam je kolekce hodnot stejných nebo různých datových typů. Pro výčet metod seznamů zadejte dir(list)

  • x = [1, 2, 3, 4], je seznam tvořený čtveřicí čísel typu int jejichž hodnoty jsou 1, 2, 3 a 4
  • y = [1, '2', 3, 4], je seznam tvořený trojicí čísel typu int jejichž hodnoty jsou 1, 3 a 4 a znakem '2'

K jednotlivým prvkům (elementům) seznamu můžeme přistupovat pomocí indexu, čísla typu int, v hranatých závorkách

  • x[0] nebo y[0] vrátí první prvek v seznamu, v obou případech se jedná o číslo 1 – v Pythonu se indexuje od 0
  • x[3] nebo y[3] vrátí poslední prvek v seznamu, v obou případech se jedná o číslo 4 – poslední prvek seznamu má index o jedna menší než je délka seznamu (počtu prvků seznamu), kterou můžeme získat funkcí len()
    • x[3] == x[len(x)-1] a y[3] == y[len(y)-1]
    • přístup k poslednímu prvku seznamu se v Pythonu může provést elegantně pomocí indexu -1: x[3] == x[-1] a y[3] == y[-1]

Pomocí indexů mohu také měnit hodnoty jednotlivých prvků v seznamu

  • y[0] = 5 změní první prvek seznamu y na 5

Ze seznamů můžeme také vybírat menší podseznamy pomocí řezů

  • x[0:3] == x[:3] == [1,2,3] což znamená, že řez je proveden od x[0] až do x[3-1]

Při vytváření řezů, můžeme zadat také krok, s jakým se seznam bude procházet

  • x[1:4:2] = [2,4] nebo x[::2] = [1,3] projde celý seznam s krokem 2
  • pokud zadáme záporný krok, seznam bude procházen pospátku: x[::-2] = [4,2]

# bunka pro hrani se seznamy

Jelikož jsou indexy seznamu celá čísla a seznamy mohou obecně nabývat spousty hodnot, je vhodné se seznamy pracovat pomocí cyklů

seznam = [1, 3, 6]  # vytvorime 1D seznam
 
 
for i in seznam:  # k jednotlivycm prvkum seznamu muzeme pristupovat napriklad ve for cyklu
    print(i, end=' ')
 
print()
# nebo pomoci indexu, kdy nechame for cyklus opakovat tolikrat, kolik prvku mame v seznamu: len(seznam)
for i in range(len(seznam)): 
    print(seznam[i],end=' ')

# pro zajímavost - výstupem funkce enumerate je index prvu v seznamu i samotný prvek
print()
for i, prvek in enumerate(seznam):
    print(prvek,end=' ') 
    print(seznam[i],end=' ')

Vytvoření seznamu

  • seznam můžeme vytvářet buď přímo výčtem hodnot oddělených čárkou v hranatých závorkách: x = [1,2,3,4], někdy je vhodné takto vytvořit i prázdný seznam y = [] (inicializovat si proměnnou)
  • přidávat hodnoty do existujícího seznamu (buď prázdného nebo ne) pak můžeme pomocí metody append(): y.append(hodnota)
  • v Pythonu je k dispozici tzv. seznamová komprehenze, která vytvoří seznam na jednom řádku, např. z = [i for i in range(10)]

y = []  # prazdny seznam
 
for i in range(10):
    y.append(i)
 
print(y)
 
# append je metoda datoveho typu seznam, podivejte se na dalsi metody aplikovatelne na seznam, umoznuji napriklad vyjimani prvku, razeni seznamu atd.
 
z = [i for i in range(10)]  # stejny vysledek pomoci seznamove komprehenze
 
print(z)

Úloha 1. Fibonacciho posloupnost

Vytvořte seznam jehož prvky bude Fibonacciho posloupnost o n prvcích.

Postup ve zkratce: $$F_0=0, F_1=1, F_n=F_{n-1}+F_{n-2}$$

n = 20  # pocet prvku rady
 
# zde piste svuj kod

Úloha 2. Součet kladných čísel

Napište funkci jejímž argumentem je seznam celých čísel a která vrátí součet pozitvních čísel z daného seznamu.

seznam = [95, 23, -3, 42, 50, -39, 48, -43, 7, -31, -85, 38, 25, -38, 1, -14, 79, -55, -34, -87] #408
 
# zde piste svuj kod

Úloha 3. Přátelé Foa

Napište funkci, která vyfiltruje seznam řetězců obsahující jména.

Vyberte ta jména, která mají přesně čtyři znaky, to jsou přátelé Foa. Tato jména budou vrácena funkcí jako seznam řetězců.

Ex: vstup = [“Ryan”, “Kieran”, “Jason”, “Yous”], Výstup = [“Ryan”, “Yous”]

jmena = ["Ryan", "Kieran", "Jason", "Yous"]
 
# zde piste kod

Úloha 4. Eratostheneovo síto pro nalezení prvočísel

Napište funkci, která vrátí seznam tvořený prvočísly od prvního prvočísla až do čísla n, které bude argumentem funkce. Pro nalezení prvočísel využijte algoritmus zvaný Eratostheneovo síto.

def Sieve_of_Eratosthenes(n):
 
    list_int = [x for x in range(2,n+1)]  # make a list of integers from 2 to n
    list_mark = [True for x in range(2,n+1)] # make a list of True values of the same size as above
 
    # zde piste svuj kod

Seznam seznamů

Již bylo řečeno, že prvkem seznamu může být hodnota jakéhokoli datového typu, například seznam řetězců seznam_text = ['petr','pavel','josef']

Je tedy možné vytvořit také seznam, jehož prvky budou seznamy matice = [[1,2,3],[4,5,6],[7,8,9]]

  • matice[0][0] představuje první prvek prvního prvku seznamu, tedy první prvek v prvním řádku matice
  • výše je uveden příklad matice, ale obecně může být každý seznam v seznamu různé délky

Seznam je měnitelný datový typ, což v Pythonu znamená, že vytvoříme-li jeden seznam x = [1,2,3] a poté druhý seznam takto y = x, jakákoli manipulace se seznamem y mění také seznam x

Např. y[0] = 5

Pokud tomu chceme předejít, musíme u 1D seznamů použít například klíčové slovo list: y = list(x)

V případě, že elementy seznamu jsou další seznamy, je nejlepší pro tzv. hlubokou kopii použít funkci deepcopy z modulu copy

x = [1,2,3]
y = x
y[0] = 5
print(f'x = {x}, y = {y}')
 
y = list(x)
y[0] = 10
print(f'x = {x}, y = {y}')
 
y = x.copy() # v případě 1D listu
y[0] = 10
print(f'x = {x}, y = {y}')

import copy
 
x = [[2,3],2]
 
y = copy.deepcopy(x)
y[0][0] = 1
print(f'x = {x}, y = {y}')
 
 
y2 = list(x)  # toto je pouze melka kopie (vnitrni seznamy jsou v y2 a x stejne objekty)
y2[0][0] = 100
print(f'x = {x}, y2 = {y2}')
 
 
y3 = x.copy()  # pozor!, .copy() v tomto pripade vytvari pouze melkou kopii
y3[0][0] = 10
print(f'x = {x}, y3 = {y3}')

Vytvoření matice

  • matici můžeme vytvořit pomocí for cyklů nebo seznamové komprehenze

matice = []  # nejprve nadeklarujeme praznou matici
n_radku = 3
n_sloupcu = 3
 
for i in range(n_radku):
    radek = []
    for k in range(n_sloupcu):
        radek.append(i*n_sloupcu+k+1)
    matice.append(radek)
 
print(matice)
 
 
# pomoci seznamove komprehenze
 
matice_c = [[i*n_sloupcu + k + 1 for k in range(n_sloupcu)] for i in range(n_radku)]
 
print(matice_c)

Úloha 6. Součet matic.

Vytvořte funkci, která dostane jako argument dvojici matic a sečte je

mat1 = [[1,2,3],[0,0,0],[5,5,5]]
mat2 = [[-1,-2,-3],[1,1,1],[-3,-3,-3]]
 
def soucet_matic(mat1,mat2):
    # zde napiste svuj kod
 
 
print(soucet_matic(mat1,mat2))
 

n-tice: tuple

n-tice je neměnitelný seznam, který můžeme nadefinovat například výčtem pomocí kulatých závorek nebo příkazu tuple

t = () # An empty tuple
t = (0, 'one')
t = ('a', ['b', 'c'], (1, 2, 3))
t = tuple(range(10))

n-tice jsou užitečné například pokud necheme, aby funkce změnila hodnoty argumentů, protože v případě předání seznamu se hodnoty změní

def pricti1(z,hodnota):
    for i in range(len(z)):
        z[i] += hodnota
    return z
 
 
def pricti2(z,hodnota):
    z = list(z) # jediny rozdil mezi funkcemi
    for i in range(len(z)):
        z[i] += hodnota
    return z

# test funkce pricti1 - vsimni si vystupu
x = (1,2,3,4)   # vytvori n-tici
y = [1,2,3,4]   # vytvori seznam
 
print(pricti1(y,1))  # pujde
print('seznam y = ',y)
 
 
print(pricti1(x,1))  # nepujde
print('seznam x = ',x)

# test funkce pricti2 - vsimni si vystupu
x = (1,2,3,4)   # vytvori n-tici
y = [1,2,3,4]   # vytvori seznam
 
print(pricti2(y,1))  # pujde
print('seznam y = ',y)
 
print(pricti2(x,1))  # pujde
print('seznam x = ',x)

Množina (set)

  • Jako množina v matematice
  • Kolekce různých datových typů, která není uspořádaná – nelze tedy indexovat
  • Každý prvek je unikátní
  • Je modifikovatelná

s = set() # An empty set
s = {1, 1, 2, 2, 3} # The same as {1, 2, 3}
s = set(range(10))

# vyuziti mnoziny pro vyber unikatnich prvku v seznamu
x = [1, 1, 2, 3, 4, 5]
x_unique = list(set(x))
print(x_unique)

Úloha 7. Opakující se písmena

V AJ (a dalších jazicíh) existuje pojem Heterogram. Tento pojem označuje slovo či větu, ve které se žádné z písmen neopakuje (tedy každé písmeno je zastoupeno pouze jednou). Napište funkci, která zjistí zda je slovo heterogramem. Vraťte True nebo False. Využijte metodu .lower() pro převod slova na malá písmena.

def is_heterogram(slovo):
 
    # vas kod
 
 
slova = ['roh', 'loupak', 'polotovar', 'struhadlo', 'Ovoce', 'zamenictvi', 'scvrnkl', 'nejnezpravdepodobnostnovavatelnejsimi', 'dvacetikoruny']
 
for slovo in slova:
    if is_heterogram(slovo):
        print('Slovo {0:s} je heterogram!'.format(slovo))
    else:
        print('Slovo {0:s} není heterogram.'.format(slovo))

Slovník: dictionary

  • Každý prvek tvořený klíčem (key) a hodnotou (value)
  • Hodnoty jsou ekvivalentní seznamu, klíče slouží k indexaci

d1 = {} # An empty dictionary
d2 = dict() # An empty dictionary
d3 = dict.fromkeys(['one', 'two', 'three']) # Empty with keys 'one', 'two', 'three'
d4 = dict.fromkeys('abcde') # Empty with keys 'a', 'b', 'c', 'd', 'e'
d5 = {'one': 1, 'two': [1, 2, 3]} # By a literal
d6 = dict(zip('keys', [1, 2, 3, 4])) # {'k': 1, 'e': 2, 'y': 3, 's': 4}

  • Indexování:

d = {'a': [1, 2, 3], 'b': ['a', 'b', 'c']}
d['a'][0]
d['b']
...

d = {'Daniel': {'vek': 23, 'vaha':65, 'sourozenci':['Jan', 'Adela']},
'Jan': {'vek': 21, 'vaha':80, 'sourozenci':['Daniel, Adela']},
'Pavla': {'vek':22, 'vaha':55, 'sourozenci':['Iveta']}}
 
print(d.keys())
print(d['Daniel'].keys())
print(d['Daniel']['sourozenci'])
 
d['Cecil'] = {'vek':78, 'vaha':76, 'sourozenci':['Vitezslav']}
print(d)

Úloha 8. Třídění

Musíte roztřídit pytel plný věcí. Na každé věci je etiketa, na které je napsaný primární (a případně i sekundární) materiál, z kterého je daná věc vyrobená. Vaším úkolem je věci správně roztřídit podle materiálu (papir, sklo, organicky_material, plast). Vstupem funkce je seznam veci, výstupem je n-tice/matice.

Příklad:

veci = [
    {"typ": "jablka", "material": "organicky_material"},
    {"typ": "jogurt", "material": "organicky_material", "sekundarniMaterial": "plast"},
    {"typ": "lahev vina", "material": "sklo", "sekundarniMaterial": "papir"},
    {"typ": "krabice", "material": "papir"},
    {"typ": "igelitovy sacek", "material": "plast"},
    {"typ": "lahev piva", "material": "sklo", "sekundarniMaterial": "papir"}
]
 
vystup = (
    ["lahev vina", "krabice", "lahev piva"], #papir
    ["lahev vina", "lahev piva"], #sklo
    ["jablka", "jogurt"], #organicky_material
    ["jogurt", "igelitovy sacek"] #plast
)

def trideni(veci):
 
    # vas kod

Příklady na procvičení ve zbytku cvičení nebo doma

Úloha 9. Vrať prostřední znak - na procvičení indexace

Napište funkci, která jako argument dostane slovo a vrátí prostřední znak slova pokud je délka slova lichá nebo prostřední dvojici znaků pokud je délka slova sudá.

Příklad:

  • roh ⇒ o
  • loupak ⇒ up
  • nejnezpravdepodobnostnovavatelnejsimi ⇒ o
  • zamenictvi ⇒ ni

 

Úloha 10. Kreditní karta - na procvičení indexace

Při nákupu na internetu chceš použít kreditní/debetní kartu. Při zadávání čísel si všimneš, že jsou vždy viditelné akorát poslední 4 číslice (kvůli bezpečnosti). Dokážeš napsat funkci, která tzv. zamaskuje všechny znaky, až na poslední čtyři? Vstupem funkce je celé číslo, které je potřeba zamaskovat, a maskovací znak. V případě, že má číslo 4 číslice (či méně), vrať číslo bez maskování. V případě, že není zadán znak, použijte #.

Příklad:

  • maskovani(90273874982936,'#') ⇒ '##########2936'
  • maskovani(123,'o') ⇒ 123
  • maskovani(847563,'q') ⇒ 'qq7563'

def maskovani(cislo, znak):
 
    # vas kod

Úloha 11. Procházka po městě - na procvičení práce s metodami, podmínkami (případně se slovníkem a množinami)

Pepíček žije ve měste, kde ulice vypadají jako čtverečkový papír (stejně dlouhé a míří buď na sever, jih, východ nebo západ). Jeden den se Pepíček rozhodne, že půjde na výlet (Vyjádřeno seznamem, kde jednotlivá písmena značí orientaci. Vzdálenost je konstantní, tedy jedno písmeno = jedna jednotka vzdálenosti). Napište funkci, která určí zda se Pepíček dokázal vrátit domů nebo zda se na výletě ztratil. Použijte metodu .count().

Příklad:

  • prochazka(['j', 'j', 'v', 'j', 'z', 's', 'z', 's', 's', 'z', 'v', 'v']) ⇒ True
  • prochazka(['j', 's', 'j', 'v', 'v']) ⇒ False

def prochazka(cesta):
 
    # vas kod

Úloha 12. DNA - na procvičení práce se slovníkem, popřípadě seznamy

Deoxyribonucleic acid (DNA) nese “instrukce” pro rozvoj a funkci buněk živých organizmů. Pro více informací http://en.wikipedia.org/wiki/DNA

V řetězci DNA, symboly “A” a “T” se navzájem doplňují stejně jako “C” a “G”. Napište funkci, která dostane jako vstup jednu stranu DNA a doplní druhou stranu DNA.

Více obdobných cvičení můžete najít zde

Příklad: (vstup –> výstup)

"ATTGC" --> "TAACG"

"GTAT" --> "CATA"

def DNA_strand(dna):
    # Vas kod
 
 
DNA_strand('ATTGC')    

Úloha 13. Jsi nadpruměrný? - na procvičení práce s funkcemi a podmínkami (případně s cykly)

Prošel jsi testem a chtěl by jsi vědět, jestli byl Tvůj výsledek lepší než průměr ze všech bodů v Tvé třídě.

Napiš funkci, která má jako argument seznam se všemi body ve třídě a druhý argument je Tvé bodové ohodnocení. Funkce spočítá průměr a porovná Tváj výsledek s průměrem. Pokud je větší, vrátí True, pokud ne vrátí False

def better_than_average(body,tve_body):
    # zde vas kod
 
 
 
test_arr = [12, 23, 34, 45, 56, 67, 78, 89, 90]
better_than_average(test_arr, 69)

Úloha 14. Součin matice

Napiš funkci, která vypočítá součin matic podle pravidla o násobení matic

 

Úloha 15. Gaussova eliminace

Pokuste se implementovat Gaussovu eliminační metodu podle postupu v materiálech k předmětu ALP (úkol 3). Řešení je možné nalézt ve videu

 

Úloha 16. Continued fraction algorithm

Napište funkci, která provede tzv. continued fraction algorithm, který rozloží racionální číslo větší než 1 do tvaru $$m_0 + \frac{1}{m_1+\frac{1}{m_2+\frac{1}{m_3 + ...}}}$$

Algoritmus je posán několika kroky:

  1. začněte s n=0 a číslem $ R$ které uložíme do seznamu x[n]
  2. zaokrouhlení: m[n] = round(x[n])
  3. zbytek: r[n] = x[n] - m[n]
  4. pokud r[n] != 0, pak x[n+1] = 1/r[n] a opakuj od bodu 2., jinak ukonči algoritmus
  5. výstup je pak vektor m[n] a v případě nedokončeného algoritmu (například pokud ukončíme iteraci dříve nebo pokud číslo není možné zcela aproximovat) hodnota x[n+1]

Při implementaci buď zvolte rozložitelné reálné číslo nebo pouze několik iterací, například pomocí for cyklu.

Příklad pro $\pi = 3.14159$ a pouze jednu iteraci:

  • n=0, x[0] = 3.14159, m[0] = 3, r[0] = 0.14
  • x[1] = 1/0.14159, $\pi$ pak můžeme aproximovat jako $\pi \approx 3 + \frac{1}{7} = \frac{22}{7} $

 

Úloha 17. Ověřte správnost continued fraction algoritmu z úlohy 3.

Napište funkci, která na svém vstupu bude mít seznam s koeficinety z CFA algoritmu a provede výpočet aproximovaného čísla

Složitější varianta:

Vyjádřete zadané racionální číslo jako zlomek

 

courses/bab37zpr/tutorials/lab04.txt · Last modified: 2022/10/04 09:50 by vencovac