326 lines
18 KiB
HTML
326 lines
18 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Kapitel G09: Dictionaries & Sets</title>
|
||
<link rel="stylesheet" href="../../assets/style.css">
|
||
</head>
|
||
<body>
|
||
|
||
<header>
|
||
<div class="header-container">
|
||
<nav class="nav-links">
|
||
<a href="../../index.html">🏠 Zur Kursübersicht</a>
|
||
<span>›</span>
|
||
<a href="../08_textverarbeitung_und_strings/index.html">← Kapitel G08</a>
|
||
<span>›</span>
|
||
<span style="color: white; font-weight: 600;">Kapitel G09</span>
|
||
<span>›</span>
|
||
<a href="../10_comprehensions_datum_algorithmen/index.html">Kapitel G10 →</a>
|
||
</nav>
|
||
<div class="header-badge">Kapitel G09 • Schulabgleich 15.0</div>
|
||
<h1>Dictionaries & Sets: Schlüssel, Werte & Mengen 🗃️✨</h1>
|
||
<p>Lerne, wie du Daten in Schlüssel-Wert-Paaren organisierst, blitzschnell nachschlägst und mit mathematischen Mengen Duplikate eliminierst.</p>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="container">
|
||
|
||
<!-- 📂 Schnellzugriff & Download aller Dateien dieser Einheit -->
|
||
<div style="background: #ffffff; border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: 14px 20px; margin-bottom: 25px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; box-shadow: var(--shadow-sm);">
|
||
<div style="font-weight: 700; color: var(--text-main); display: flex; align-items: center; gap: 8px;">
|
||
<span>📂 Dateien dieser Einheit:</span>
|
||
</div>
|
||
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
|
||
<a href="aufgabe.py" class="btn" style="padding: 6px 14px; font-size: 0.88rem; background: var(--primary);" download>📄 aufgabe.py (Startercode)</a>
|
||
<a href="test_aufgabe.py" class="btn btn-secondary" style="padding: 6px 14px; font-size: 0.88rem;" download>🧪 test_aufgabe.py (Tests)</a>
|
||
<a href="musterloesung.py" class="btn btn-secondary" style="padding: 6px 14px; font-size: 0.88rem;" download>💡 musterloesung.py (Lösung)</a>
|
||
<a href="README.md" class="btn btn-secondary" style="padding: 6px 14px; font-size: 0.88rem;">📖 README.md</a>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- 1. Dictionaries: Die Karteikasten-Analogie -->
|
||
<section class="card">
|
||
<h2>1. Was ist ein Dictionary? (Die Karteikasten-Analogie)</h2>
|
||
|
||
<p>
|
||
Bisher hast du Daten oft in <strong>Listen</strong> gespeichert. Bei einer Liste greifst du über eine Zahl (den Index <code>0, 1, 2, ...</code>) auf Einträge zu.
|
||
Aber was machst du, wenn du eine Telefonnummer zu einem <em>Namen</em> suchst oder eine deutsche Übersetzung zu einem <em>englischen Wort</em>?
|
||
</p>
|
||
|
||
<div class="box box-analogie">
|
||
<div class="box-title">🗃️ Die Karteikasten- & Wörterbuch-Analogie:</div>
|
||
<p>Ein <strong>Dictionary</strong> (Wörterbuch) funktioniert wie ein echter Karteikasten:</p>
|
||
<ul style="margin-left: 20px; margin-top: 8px;">
|
||
<li>Vorne auf der Karteikarte steht das <strong>Stichwort (der Key / Schlüssel)</strong>, z.B. <code>"Anna"</code>.</li>
|
||
<li>Auf der Rückseite steht die eigentliche <strong>Information (der Value / Wert)</strong>, z.B. <code>"0171-123456"</code>.</li>
|
||
<li>Du musst nicht alle Karten von vorne bis hinten durchblättern – Python springt <strong>sofort in Lichtgeschwindigkeit</strong> zum gesuchten Schlüssel!</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="code-container">
|
||
<div class="code-header">
|
||
<div class="code-dots">
|
||
<span class="code-dot dot-red"></span>
|
||
<span class="code-dot dot-yellow"></span>
|
||
<span class="code-dot dot-green"></span>
|
||
</div>
|
||
<span>Python: Dictionary Grundlagen</span>
|
||
</div>
|
||
<pre><span class="cm"># 1. Dictionary erstellen mit geschweiften Klammern {key: value}:</span>
|
||
<span class="var">kontakt</span> = {
|
||
<span class="str">"name"</span>: <span class="str">"Anna"</span>,
|
||
<span class="str">"alter"</span>: <span class="num">23</span>,
|
||
<span class="str">"beruf"</span>: <span class="str">"Entwicklerin"</span>
|
||
}
|
||
|
||
<span class="cm"># 2. Wert über Schlüssel abrufen:</span>
|
||
<span class="fn">print</span>(<span class="var">kontakt</span>[<span class="str">"name"</span>]) <span class="cm"># Gibt "Anna" aus</span>
|
||
|
||
<span class="cm"># 3. Eintrag hinzufügen oder verändern:</span>
|
||
<span class="var">kontakt</span>[<span class="str">"stadt"</span>] = <span class="str">"Berlin"</span> <span class="cm"># Neu hinzugefügt</span>
|
||
<span class="var">kontakt</span>[<span class="str">"alter"</span>] = <span class="num">24</span> <span class="cm"># Wert aktualisiert</span>
|
||
|
||
<span class="cm"># 4. Eintrag löschen:</span>
|
||
<span class="kw">del</span> <span class="var">kontakt</span>[<span class="str">"beruf"</span>] <span class="cm"># Entfernt den Schlüssel "beruf"</span></pre>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 2. Sicherer Zugriff mit .get() & Dict-Methoden -->
|
||
<section class="card">
|
||
<h2>2. Sicherer Datenzugriff mit <code>.get()</code> & Iteration</h2>
|
||
|
||
<p>
|
||
Greifst du auf einen Schlüssel zu, den es im Dictionary nicht gibt, stürzt dein Programm mit einem gefürchteten <code>KeyError</code> ab!
|
||
</p>
|
||
|
||
<div class="box box-warning">
|
||
<div class="box-title">🛡️ Die Lebensversicherung: <code>dict.get(key, standardwert)</code></div>
|
||
Verwende <code>.get()</code>, wenn du nicht sicher weißt, ob der Schlüssel existiert. Statt abzustürzen, liefert Python einen sicheren Standardwert zurück!
|
||
</div>
|
||
|
||
<div class="code-container">
|
||
<div class="code-header">
|
||
<span>Vergleich: dict[key] vs dict.get()</span>
|
||
</div>
|
||
<pre><span class="var">user</span> = {<span class="str">"username"</span>: <span class="str">"coder99"</span>}
|
||
|
||
<span class="cm"># ❌ Riskant: Programm stürzt bei fehlendem Key ab!</span>
|
||
<span class="cm"># print(user["email"]) # 💥 KeyError: 'email'</span>
|
||
|
||
<span class="cm"># ✅ Sicher: Liefert Fallback-Wert ohne Absturz!</span>
|
||
<span class="var">email</span> = <span class="var">user</span>.<span class="fn">get</span>(<span class="str">"email"</span>, <span class="str">"Keine E-Mail angegeben"</span>)
|
||
<span class="fn">print</span>(<span class="var">email</span>) <span class="cm"># Ausgabe: Keine E-Mail angegeben</span></pre>
|
||
</div>
|
||
|
||
<h3>Praktische Methoden: <code>.keys()</code>, <code>.values()</code> und <code>.items()</code></h3>
|
||
|
||
<div class="code-container">
|
||
<div class="code-header">
|
||
<span>Schleifen über Dictionaries</span>
|
||
</div>
|
||
<pre><span class="var">preise</span> = {<span class="str">"Kaffee"</span>: <span class="num">3.50</span>, <span class="str">"Croissant"</span>: <span class="num">2.20</span>, <span class="str">"Tee"</span>: <span class="num">2.80</span>}
|
||
|
||
<span class="cm"># Schlüssel und Werte gleichzeitig durchlaufen mit .items():</span>
|
||
<span class="kw">for</span> <span class="var">produkt</span>, <span class="var">preis</span> <span class="kw">in</span> <span class="var">preise</span>.<span class="fn">items</span>():
|
||
<span class="fn">print</span>(<span class="str">f"{produkt} kostet {preis:.2f} €"</span>)</pre>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 3. Sets: Die Club-Türsteher-Analogie -->
|
||
<section class="card">
|
||
<h2>3. Was ist ein Set (Menge)? (Die Club-Türsteher-Analogie)</h2>
|
||
|
||
<p>
|
||
Ein <strong>Set</strong> (Menge) ist eine Sammlung von Elementen mit zwei besonderen Superkräften:
|
||
<strong>1. Keine Duplikate erlaubt</strong> und <strong>2. Extrem schnelle Suche (in O(1))</strong>.
|
||
</p>
|
||
|
||
<div class="box box-analogie">
|
||
<div class="box-title">🚪 Die Club-Türsteher-Analogie:</div>
|
||
<p>
|
||
Stell dir einen Club vor, in dem jeder Gast genau <strong>einmal</strong> auf die Gästeliste darf:
|
||
</p>
|
||
<ul style="margin-left: 20px; margin-top: 8px;">
|
||
<li>Versucht jemand doppelt hineinzugehen, ignoriert der Türsteher den zweiten Versuch einfach.</li>
|
||
<li>Es gibt im Club keine feste Sitzordnung (Sets sind <em>ungeordnet</em> und haben keinen Index wie <code>set[0]</code>).</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="code-container">
|
||
<div class="code-header">
|
||
<span>Sets erstellen und Duplikate filtern</span>
|
||
</div>
|
||
<pre><span class="cm"># Set erstellen (Duplikate fallen automatisch weg):</span>
|
||
<span class="var">zahlen</span> = {<span class="num">1</span>, <span class="num">2</span>, <span class="num">2</span>, <span class="num">3</span>, <span class="num">3</span>, <span class="num">3</span>, <span class="num">4</span>}
|
||
<span class="fn">print</span>(<span class="var">zahlen</span>) <span class="cm"># Ausgabe: {1, 2, 3, 4}</span>
|
||
|
||
<span class="cm"># Blitzschnelle Überprüfung mit 'in':</span>
|
||
<span class="kw">if</span> <span class="num">3</span> <span class="kw">in</span> <span class="var">zahlen</span>:
|
||
<span class="fn">print</span>(<span class="str">"3 ist in der Menge enthalten!"</span>)
|
||
|
||
<span class="cm"># ⚠️ Achtung beim leeren Set:</span>
|
||
<span class="var">leeres_dict</span> = {} <span class="cm"># Erzeugt ein leeres Dictionary!</span>
|
||
<span class="var">leeres_set</span> = <span class="fn">set</span>() <span class="cm"># ✅ So erstellst du ein leeres Set!</span></pre>
|
||
</div>
|
||
|
||
<h3>Mengenoperationen im Überblick</h3>
|
||
|
||
<table style="width: 100%; border-collapse: collapse; margin: 15px 0;">
|
||
<thead>
|
||
<tr style="background: var(--primary-light); text-align: left;">
|
||
<th style="padding: 10px; border: 1px solid var(--border-color);">Operation</th>
|
||
<th style="padding: 10px; border: 1px solid var(--border-color);">Operator</th>
|
||
<th style="padding: 10px; border: 1px solid var(--border-color);">Methode</th>
|
||
<th style="padding: 10px; border: 1px solid var(--border-color);">Bedeutung</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);"><strong>Schnittmenge (Intersection)</strong></td>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);"><code>A & B</code></td>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);"><code>A.intersection(B)</code></td>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);">Gemeinsame Elemente beider Mengen</td>
|
||
</tr>
|
||
<tr style="background: #fafafa;">
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);"><strong>Vereinigung (Union)</strong></td>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);"><code>A | B</code></td>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);"><code>A.union(B)</code></td>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);">Alle Elemente aus A und B zusammen</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);"><strong>Differenz</strong></td>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);"><code>A - B</code></td>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);"><code>A.difference(B)</code></td>
|
||
<td style="padding: 10px; border: 1px solid var(--border-color);">Elemente in A, die NICHT in B vorkommen</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<!-- 4. Vollständiges Praxisbeispiel -->
|
||
<section class="card">
|
||
<h2>4. 🌟 Vollständiges Praxisbeispiel: Wörter-Zähler</h2>
|
||
|
||
<p>Hier siehst du, wie man mit Dictionaries Wort-Häufigkeiten in Texten ermittelt:</p>
|
||
|
||
<div class="code-container">
|
||
<div class="code-header">
|
||
<div class="code-dots">
|
||
<span class="code-dot dot-red"></span>
|
||
<span class="code-dot dot-yellow"></span>
|
||
<span class="code-dot dot-green"></span>
|
||
</div>
|
||
<span>Python: Wort-Häufigkeiten zählen</span>
|
||
</div>
|
||
<pre><span class="kw">def</span> <span class="fn">zaehle_woerter</span>(<span class="var">text</span>):
|
||
<span class="var">haeufigkeit</span> = {}
|
||
<span class="var">woerter</span> = <span class="var">text</span>.<span class="fn">lower</span>().<span class="fn">split</span>()
|
||
|
||
<span class="kw">for</span> <span class="var">wort</span> <span class="kw">in</span> <span class="var">woerter</span>:
|
||
<span class="cm"># Wenn das Wort noch nicht im Dict ist, startet der Zähler bei 0:</span>
|
||
<span class="var">haeufigkeit</span>[<span class="var">wort</span>] = <span class="var">haeufigkeit</span>.<span class="fn">get</span>(<span class="var">wort</span>, <span class="num">0</span>) + <span class="num">1</span>
|
||
|
||
<span class="kw">return</span> <span class="var">haeufigkeit</span>
|
||
|
||
<span class="var">beispiel</span> = <span class="str">"Python macht Spaß und Python ist mächtig"</span>
|
||
<span class="fn">print</span>(<span class="fn">zaehle_woerter</span>(<span class="var">beispiel</span>))
|
||
<span class="cm"># Ausgabe: {'python': 2, 'macht': 1, 'spaß': 1, 'und': 1, 'ist': 1, 'mächtig': 1}</span></pre>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 5. Aufgaben & Checkliste -->
|
||
<section class="card">
|
||
<h2>5. 🎯 Deine Aufgaben in <code><a href="aufgabe.py" style="color: inherit; text-decoration: underline;">aufgabe.py</a></code></h2>
|
||
|
||
<p>Öffne die Datei <code><a href="aufgabe.py" style="color: inherit; text-decoration: underline;">aufgabe.py</a></code> und bearbeite die folgenden 4 Aufgaben:</p>
|
||
|
||
<ul class="task-list">
|
||
<li class="task-item">
|
||
<input type="checkbox" class="task-checkbox" id="t1">
|
||
<label for="t1" class="task-label">
|
||
<strong>TODO 1 (<code>woerter_haeufigkeit</code>):</strong> Bereinige den Text von Satzzeichen, wandle ihn in Kleinbuchstaben um und zähle, wie oft jedes Wort vorkommt.
|
||
</label>
|
||
</li>
|
||
<li class="task-item">
|
||
<input type="checkbox" class="task-checkbox" id="t2">
|
||
<label for="t2" class="task-label">
|
||
<strong>TODO 2 (<code>telefonbuch_suche</code>):</strong> Verwende <code>.get()</code>, um eine Telefonnummer sicher abzufragen (liefert <code>"Nicht gefunden"</code> bei unbekanntem Namen).
|
||
</label>
|
||
</li>
|
||
<li class="task-item">
|
||
<input type="checkbox" class="task-checkbox" id="t3">
|
||
<label for="t3" class="task-label">
|
||
<strong>TODO 3 (<code>gemeinsame_interessen</code>):</strong> Finde mit der Schnittmenge (<code>&</code>) die Hobbys, die zwei Personen gemeinsam teilen.
|
||
</label>
|
||
</li>
|
||
<li class="task-item">
|
||
<input type="checkbox" class="task-checkbox" id="t4">
|
||
<label for="t4" class="task-label">
|
||
<strong>TODO 4 (<code>entferne_duplikate_behalte_reihenfolge</code>):</strong> Entferne doppelte Elemente aus einer Liste, ohne die ursprüngliche Reihenfolge zu verändern (Tipp: Hilfsmenge <code>seen = set()</code>).
|
||
</label>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3>💡 Lösungshinweise (Aufklappen bei Bedarf)</h3>
|
||
|
||
<details>
|
||
<summary>🔍 Tipp zu TODO 1 (Satzzeichen entfernen & Zählen)</summary>
|
||
<div class="details-content">
|
||
<p>Du kannst Satzzeichen mit <code>replace()</code> durch Leerzeichen ersetzen und dann mit <code>.get(wort, 0) + 1</code> zählen:</p>
|
||
<div class="code-container">
|
||
<pre><span class="var">bereinigt</span> = <span class="var">text</span>.<span class="fn">lower</span>()
|
||
<span class="kw">for</span> <span class="var">zeichen</span> <span class="kw">in</span> <span class="str">".,!?;:()\"'"</span>:
|
||
<span class="var">bereinigt</span> = <span class="var">bereinigt</span>.<span class="fn">replace</span>(<span class="var">zeichen</span>, <span class="str">" "</span>)
|
||
<span class="var">woerter</span> = <span class="var">bereinigt</span>.<span class="fn">split</span>()</pre>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details>
|
||
<summary>🔍 Tipp zu TODO 4 (Reihenfolge bei Duplikaten behalten)</summary>
|
||
<div class="details-content">
|
||
<p>Nutze eine Liste für das Ergebnis und ein Set zum Merken bereits gesehener Elemente:</p>
|
||
<div class="code-container">
|
||
<pre><span class="var">seen</span> = <span class="fn">set</span>()
|
||
<span class="var">ergebnis</span> = []
|
||
<span class="kw">for</span> <span class="var">element</span> <span class="kw">in</span> <span class="var">liste</span>:
|
||
<span class="kw">if</span> <span class="var">element</span> <span class="kw">not in</span> <span class="var">seen</span>:
|
||
<span class="var">seen</span>.<span class="fn">add</span>(<span class="var">element</span>)
|
||
<span class="var">ergebnis</span>.<span class="fn">append</span>(<span class="var">element</span>)
|
||
<span class="kw">return</span> <span class="var">ergebnis</span></pre>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
</section>
|
||
|
||
<!-- 6. Testen & Navigation -->
|
||
<section class="card">
|
||
<h2>6. 🧪 Lösung überprüfen</h2>
|
||
<p>Führe im Terminal die automatische Test-Suite aus:</p>
|
||
<div class="code-container">
|
||
<div class="code-header">
|
||
<span>Terminal</span>
|
||
</div>
|
||
<pre><code>python3 test_aufgabe.py</code></pre>
|
||
</div>
|
||
|
||
<div class="footer-nav">
|
||
<a href="../08_textverarbeitung_und_strings/index.html" class="btn btn-secondary">← Zurück zu Kapitel G08</a>
|
||
<a href="../10_comprehensions_datum_algorithmen/index.html" class="btn">Weiter zu Kapitel G10: Comprehensions & Algorithmen →</a>
|
||
</div>
|
||
</section>
|
||
|
||
</main>
|
||
|
||
|
||
<!-- Lokale Gamification-Scripts (funktionieren auch offline per Doppelklick via file://) -->
|
||
<script src="../../assets/gamification_data.js"></script>
|
||
<script src="../../assets/gamification.js"></script>
|
||
<script src="../../assets/parsons.js"></script>
|
||
<script src="../../assets/interpreter.js"></script>
|
||
<script src="../../assets/ui_enhancements.js"></script>
|
||
</body>
|
||
</html>
|