Výuka

Cvičení 29. 10. 2026 – List & Dictionary Comprehension in Python

Basics

V Pythonu máme k dispozici 4 hlavní datové struktury:

Seznam

Seznam je posloupnost prvků. Každý prvek této posloupnosti může být jiný.

seznam1 = [0]
seznam2 = [1, 2, "ahoj", ["seznam může být i v jiném seznamu", 0, -10], seznam1]

# Indexují se standardně od 0:
print(seznam2[2])
# Output: ahoj

Seznamy zachovávají pořadí prvků a jsou v čase měnitelné – lze z nich prvky libovolně mazat a přidávat:

seznam = [1, 2, 3, "brno", "praha", "brno"]

# Odstranit specifický prvek (pouze jeho první výskyt)
seznam.remove("brno")
# print(seznam) => [1, 2, 3, "praha", "brno"]

# Odstranění posledního prvku
seznam.pop()
# print(seznam) => [1, 2, 3, "praha"]

# Přidání na konec seznamu
seznam.append(5)
# print(seznam) => [1, 2, 3, "praha", 5]

# Přidání na lib. pozici, místo opět určené od 0
seznam.insert(2, "olomouc")
# print(seznam) => [1, 2, "olomouc", 3, "praha", 5]

# Nahrazení prvku jiným
seznam[3] = 4
# print(seznam) => [1, 2, "olomouc", 4, "praha", 5]
# Vytvoření seznamu s předem daným počtem stejných prvků
seznam = [0] * 4
# print(seznam) => [0, 0, 0, 0]

# Seznamy procházíme prvek po prvku for-loopem
for i in range(len(seznam)):
    print(seznam[i])
# Output:
# 0
# 0
# 0
# 0

# Jestli seznam obsahuje nějaký konkrétní prvek
0 in seznam # True
4 in seznam # False
"nula" in seznam # False

Většinu času pro záznam nějaké posloupnosti si člověk vystačí se seznamem, ale existují i specifické případy, kdy dává smysl použít Tuple nebo Set.

Tuple

Tuple je podobný seznamu, ale je v čase neměnný – po vytvoření z něj nelze nic odebrat ani do něj přidat ani nahradit prvek jiným.

# Pro vytvoření se používají klasické závorky ()
trojice = (1, 2, "lampička")

# Indexuje se standardně jako seznam
print(trojice[2])
# Output: lampička

Většinou si člověk vystačí se seznamem a není povinností používat Tuple, pokud se dopředu ví, že se data nebudou měnit. Jeho použití ale může pomoct v kódu komunikovat to, že se očekává, že hodnota proměnné se nebude měnit.

Příkladem použití může být například konkrétní zápis souřadnic nějaké budovy na mapě – budovy se většinou nehýbou (pokud zrovna nejste kostel v komunistickém Československu).

Set

Oproti seznamu nezachovává pořadí prvků – ze setu tedy není možné získat libovolný prvek podle indexu, můžeme se ale zeptat, zdali se nějaký konkrétní prvek v daném setu nachází. Zároveň nemůže obsahovat žádný prvek víckrát. Je v čase měnitelný, takže do něj lze přidávat i z něj odstraňovat prvky.

# Pro vytvoření se používají závorky {}
mnozina = {1, 1, 2, 9, 10, "proc"}
# print(mnozina) => {1, 2, 'proc', 9, 10}
# upozornění: `{}` samo o sobě vytvoří prázdný slovník,
# nikoliv prázdnou množinu, ta se vytvoří pomocí `set()`

# Přidání prvku
mnozina.add("pomeranc")
# print(mnozina) => {1, 2, "pomeranc", "proc", 10, 9}

# Odstranění prvku
mnozina.discard("pomeranc")
# print(mnozina) => {1, 2, "proc", 10, 9}

# Nelze získat prvek podle indexu z množiny!
# print(mnozina[3]) hodí Error!

# Lze se ale ptát, zdali prvek je v množině, nebo není
print(3 in mnozina) # False
print(1 in mnozina) # True

# Mnozinové operace
a = { 1, 2, 3 }
b = { 2, 3, 4 }
# Sjednocení
print(a | b)
# Output: {1, 2, 3, 4}
# Průnik
print(a & b)
# Output: {2, 3}
# Rozdíl
print(a - b, b - a)
# Output: {1} {4}
# Symetrická diference
print(a ^ b)
# Output: {1, 4}

# Množiny lze také procházet,
# nelze ale spoléhat na správné pořadí
for prvek in mnozina:
    print(prvek)
# Output:
# 1
# 2
# proc
# 10
# 9

# Existuje neměnná varianta množiny, tzv. `frozenset`
# Chová se stejně jako množina, ale nelze měnit prvky po vytvoření
frozen = frozenset({1, 1, 2, 3, 4, 4})
print(frozen)
# Output: frozenset({1, 2, 3, 4})

Časté využití množin je takový hack: mám seznam různých prvků, chci zjistit, jaké jedinečné prvky v něm jsou, aniž bych se zabýval jejich duplikáty: řešením je převést seznam na množinu a buď s ní pracovat, nebo ji převést zpět na seznam, čímž získáme seznam, ve kterém je každý prvek jen jednou. Ale nemusí se zachovat původní pořadí prvků.

Slovník

Fungovat se slovníky je velmi důležité. Nejdřív je ale podstatné uvědomit si, k čemu takový slovník může být. A co vlastně má popisovat. Můžeme si představit slovník jako popis nějakého objektu a jeho určitých vlastností, např. člověka, předmětu, státu, … Slovníky totiž v sobě ukládají data vždy ve dvojicích klíč-hodnota. V jednom slovníku se nemůže opakovat stejný klíč, ale víc klíčů může mít stejnou hodnotu. Slovníky jsou proměnné v čase.

# Slovníky se píšou do {}, dvojice klíč-hodnota se oddělují čárkou
# klíč je většinou nějaký string, ale může to být i např. číslo nebo tuple
clovek = {
    "jmeno": "Jan",
    "prijmeni": "Noha",
    "vek": 18,
}

zidle = {
    "barva": "hneda",
    "vyska": 100,
    "podsedak": True,
    "polohovaci": False,
}

# Přístup k hodnotám ve slovníku je přes klíče
print(zidle["vyska"])
# Output: 100

# Přidání nové dvojice klíč-hodnota je stejné jako úprava již existující dvojice
clovek["pocet_oci"] = 2
clovek["vek"] = 20

# Odstranění dvojice přes klíč
del zidle["barva"]

# Můžeme procházet slovník přes jeho klíče
for klic in clovek.keys():
    print(klic)
# Output:
# jmeno
# prijmeni
# vek
# pocet_oci
# Poznámka: klíče jsou ve slovníku seřazeny podle pořadí přidání do slovníku

# Nebo přes hodnoty
for hodnota in clovek.values():
    print(hodnota)
# Output:
# Jan
# Noha
# 20
# 2

# Nebo přes dvojice klíč-hodnota
for klic, hodnota in clovek.items():
    print(klic, hodnota)
# Output:
# jmeno Jan
# prijmeni Noha
# vek 20
# pocet_oci 2

# Můžeme zkontrolovat, jestli klíč ve slovníku existuje
print("pocet_oci" in clovek) # True
print("pocet_oci" in zidle) # False

Zajímavé funkce

Mezi seznamy, tuply a množinami můžeme většinou převádět stejně jako můžeme převést např. string na int:

seznam = [1, 2, 2]
mnozina = {1, 1, 1}
trojice = (1, 1, 2)

# Převedení na množinu
print(set(seznam))
# Output: {1, 2}
print(set(trojice))
# Output: {1, 2}

# Převedení na seznam
print(list(trojice))
# Output: [1, 1, 2]
print(list(mnozina))
# Output: [1]

# Převedení na tuple
print(tuple(mnozina))
# Output: (1,)
# pozn.: zápis (1) by představoval samotné číslo 1
print(tuple(seznam))
# Output: (1, 2, 2)
# zip() spojí 2 seznamy, vždy i-tý prvek z jednoho s i-tým prvkem z druhého
# pozn.: funguje i s jinými strukturami než jen se seznamy
ovoce = ["jablka", "hrušky", "pomeranče"]
skladem = [18, 20, 9]
for o, s in zip(ovoce, skladem):
    print(o, s)
# Output:
# jablka 18
# hrušky 20
# pomeranče 9

# Lze sestrojit seznam přiřazených hodnot
print(list(zip(ovoce, skladem)))
# Output: [("jablka", 18), ("hrušky", 20), ("pomeranče", 9)]

# Nebo sestrojit slovník
uroda = dict(zip(ovoce, skladem))
print(uroda)
# Output:
# {
#    "jablka": 18,
#    "hrušky": 20,
#    "pomeranče": 9,
# }
# print(uroda) vypíše na jeden řádek; uvedeno na více řádcích pro lepší čitelnost
# Funkce string.isalpha() kontroluje, jestli je string tvořen pouze písmenky abecedy
# pokud ano, vrací True, ale pozor: funguje napříč všemi abecedami světa
"abclkjadhfpiq".isalpha() # True
"fas74890fas".isalpha() # False
"afsdafę".isalpha() # True
"českárepublika".isalpha() # True
"ceska republika".isalpha() # False
"borekstavitel!".isalpha() # False
# Pro vytvoření matice lze použít seznam seznamů
matice = [
    [1, 2, 3],
    [2, 4, 5],
    [6, 7, 9],
]

# oproti klasické matematice nesmíme zapomenout, že index jde od 0
print(matice[1][1])
# Output: 4

List Comprehension

1. The Basics: Traditional Loop vs. List Comprehension

# Goal: Create a list of squares for numbers 0 through 4
# Traditional approach:
squares_loop = []
for i in range(5):
    squares_loop.append(i ** 2)
print(squares_loop)
# Output: [0, 1, 4, 9, 16]

# List Comprehension approach:
squares_comp = [i ** 2 for i in range(5)]
print(squares_comp)
# Output: [0, 1, 4, 9, 16]

2. Filtering with an IF condition

# The expression is only executed if the condition at the end is True.
numbers = [1, 2, 3, 4, 5, 6]
evens = [n for n in numbers if n % 2 == 0]
print(evens)
# Output: [2, 4, 6]

3. String Manipulation

# You can perform method calls or operations directly on the items.
names = ["alice", "bob", "charlie"]
capitalized = [name.capitalize() for name in names]
print(capitalized)
# Output: ['Alice', 'Bob', 'Charlie']

4. Complex Expressions (If/Else)

# If you need an IF/ELSE, it moves to the front (before the FOR loop).
# You can't use it to filter through the elements but only to pick the final value.
# Goal: Tag numbers as "Even" or "Odd"
tags = ["Even" if n % 2 == 0 else "Odd" for n in range(4)]
print(tags)
# Output: ['Even', 'Odd', 'Even', 'Odd']

Dictionary Comprehension

1. Basic Generation

# Goal: Create a dictionary mapping numbers to their squares
squares = {x: x**2 for x in range(1, 6)}
print(squares)  
# Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

2. Creating a Dictionary from Two Lists

# Using zip() pairs the elements together
keys = ["name", "role", "age"]
values = ["Alice", "Admin", 28]
user_dict = {k: v for k, v in zip(keys, values)}
print(user_dict)  
# Output: {'name': 'Alice', 'role': 'Admin', 'age': 28}

3. Filtering an Existing Dictionary

# Goal: Keep only the items that cost less than 50
prices = {"apple": 1.20, "banana": 0.80, "steak": 15.50, "caviar": 85.00}
cheap_items = {item: price for item, price in prices.items() if price < 50.00}
print(cheap_items)  
# Output: {'apple': 1.2, 'banana': 0.8, 'steak': 15.5}

4. Inverting a Dictionary (Flipping Keys and Values)

# Useful for reverse lookups, assuming all values are unique
id_to_name = {101: "Alice", 102: "Bob", 103: "Charlie"}
name_to_id = {name: emp_id for emp_id, name in id_to_name.items()}
print(name_to_id)  
# Output: {'Alice': 101, 'Bob': 102, 'Charlie': 103}

Example Problem

You are building an e-commerce backend. You receive a raw API payload containing a list of product records. You need to complete two tasks efficiently:

  1. Generate a reorder list containing just the names of active products with a stock level below 20.

  2. Build a fast-lookup catalog that maps the id of every active product directly to its price.

# Raw JSON-like data from an API
inventory = [
    {"id": "A1", "name": "Wireless Mouse", "price": 25.99, "stock": 12, "active": True},
    {"id": "A2", "name": "Mechanical Keyboard", "price": 89.99, "stock": 45, "active": True},
    {"id": "A3", "name": "USB-C Cable", "price": 14.50, "stock": 5, "active": True},
    {"id": "A4", "name": "Old Mousepad", "price": 5.00, "stock": 0, "active": False},
    {"id": "A5", "name": "Laptop Stand", "price": 42.00, "stock": 18, "active": True}
]

Solution

1. List Comprehension: Extract names based on multiple conditions

reorder_list = [item["name"] for item in inventory if item["active"] and item["stock"] < 20]

print(f"Reorder needed: {reorder_list}")
# Output: Reorder needed: ['Wireless Mouse', 'USB-C Cable', 'Laptop Stand']

2. Dictionary Comprehension: Map ID to Price for active items

price_catalog = {item["id"]: item["price"] for item in inventory if item["active"]}

print(f"Price catalog: {price_catalog}")
# Output: Price catalog: {'A1': 25.99, 'A2': 89.99, 'A3': 14.5, 'A5': 42.0}

Example Problem #2

Flatten a list of lists into a single flat list using a nested list comprehension.

matrix = [
    [1, 2, 3], 
    [4, 5], 
    [6, 7, 8, 9]
]

Solution

1. The Traditional Nested Loop

flat_traditional = []
for row in matrix:          # OUTER loop
    for num in row:         # INNER loop
        flat_traditional.append(num)

print(flat_traditional)     
# Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]

2. The Nested List Comprehension

# Notice how the loops appear in the exact same left-to-right order
flat_comp = [num for row in matrix for num in row]

print(flat_comp)            
# Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]

3. Adding Conditions

# You can still filter data by adding an IF statement at the very end.
# Goal: Flatten the list, but only keep even numbers.
even_flat = [num for row in matrix for num in row if num % 2 == 0]

print(even_flat)
# Output: [2, 4, 6, 8]