N-tice

Už víš, že pomocí return lze z funkce vracet hodnotu:

def dvojnasobek(x):
    return x * 2

Jak ale napsat funkci, která vrátí dvě hodnoty? Chci třeba napsat funkci, která spočítá podíl a zbytek po dělení.

Dvě hodnoty se dají vrátit jako seznam:

def podil_a_zbytek(a, b):
    podil = a // b
    zbytek = a % b

    return [podil, zbytek]

print(podil_a_zbytek(5, 2))

Lepší je ale vrátit dvojici čísel – dvě čísla oddělená čárkou:

def podil_a_zbytek(a, b):
    podil = a // b
    zbytek = a % b

    return podil, zbytek

print(podil_a_zbytek(5, 2))

Tomuhle se říká dvojice – nebo trojice, čtveřice, pětice, šestice, prostě n-tice (angl. tuple) hodnot. Funguje podobně jako seznam, ale nedají se do ní přidávat prvky, nebo odebírat a jinak měnit. Když mám trojici, vždycky zůstane jako trojice.

Když máš n-tici, můžeš ji přiřazením rozbalit (angl. unpack) do několika proměnných:

podil, zbytek = podil_a_zbytek(5, 2)

print(podil)
print(zbytek)

N-tice mají spoustu využití, například:

  • Bod v prostoru má 3 souřadnice – trojice čísel!
  • Hrací karta má barvu a hodotu – dvojice čísla a řetězce, např. (2, 'piky')

Občas je potřeba dát n-tice do seznamu, např. abys uložil/a informace o celém balíčku hracích karet. V podobných případech je potřeba každou n-tici uzavřít do závorek, aby bylo jasné kde začíná a kde končí. Tady je seznam dvojic:

ruka = [(2, 'piky'), (10, 'kříže'), (8, 'káry')]

Když takový seznam máš, můžeš ho projít v cyklu for s pomocí rozbalování:

for hodnota, barva in ruka:
    print('Hraju', hodnota, 'a jsou to', barva)

Zip

N-tice, respektive sekvenci n-tic vrací funkce zip, která umožňuje projít zároveň několik seznamů, jejichž prvky si navzájem odpovídají:

veci = ['tráva', 'slunce', 'mrkev', 'řeka']
barvy = ['zelená', 'žluté', 'oranžová', 'modrá']
mista = ['na zemi', 'nahoře', 'na talíři', 'za zídkou']

for vec, barva, misto in zip(veci, barvy, mista):
    print(barva, vec, 'je', misto)
{
  "data": {
    "sessionMaterial": {
      "id": "session-material:2018/snake-brno-codeweek:intro:13",
      "title": "N-tice a rozbalování",
      "html": "\n          \n    \n\n    <h1><var>N</var>-tice</h1>\n<p>U&#x17E; v&#xED;&#x161;, &#x17E;e pomoc&#xED; <code>return</code> lze z&#xA0;funkce vracet hodnotu:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">dvojnasobek</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">x</span> <span class=\"o\">*</span> <span class=\"mi\">2</span>\n</pre></div><p>Jak ale napsat funkci, kter&#xE1; vr&#xE1;t&#xED; dv&#x11B; hodnoty?\nChci t&#x159;eba napsat funkci, kter&#xE1; spo&#x10D;&#xED;t&#xE1; pod&#xED;l a zbytek po d&#x11B;len&#xED;.</p>\n<p>Dv&#x11B; hodnoty se daj&#xED; vr&#xE1;tit jako seznam:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">podil_a_zbytek</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n    <span class=\"n\">podil</span> <span class=\"o\">=</span> <span class=\"n\">a</span> <span class=\"o\">//</span> <span class=\"n\">b</span>\n    <span class=\"n\">zbytek</span> <span class=\"o\">=</span> <span class=\"n\">a</span> <span class=\"o\">%</span> <span class=\"n\">b</span>\n\n    <span class=\"k\">return</span> <span class=\"p\">[</span><span class=\"n\">podil</span><span class=\"p\">,</span> <span class=\"n\">zbytek</span><span class=\"p\">]</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">podil_a_zbytek</span><span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">))</span>\n</pre></div><p>Lep&#x161;&#xED; je ale vr&#xE1;tit <em>dvojici</em> &#x10D;&#xED;sel &#x2013; dv&#x11B; &#x10D;&#xED;sla odd&#x11B;len&#xE1; &#x10D;&#xE1;rkou:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">podil_a_zbytek</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n    <span class=\"n\">podil</span> <span class=\"o\">=</span> <span class=\"n\">a</span> <span class=\"o\">//</span> <span class=\"n\">b</span>\n    <span class=\"n\">zbytek</span> <span class=\"o\">=</span> <span class=\"n\">a</span> <span class=\"o\">%</span> <span class=\"n\">b</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">podil</span><span class=\"p\">,</span> <span class=\"n\">zbytek</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">podil_a_zbytek</span><span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">))</span>\n</pre></div><p>Tomuhle se &#x159;&#xED;k&#xE1; dvojice &#x2013; nebo trojice, &#x10D;tve&#x159;ice, p&#x11B;tice, &#x161;estice, prost&#x11B;\n<var>n</var>-tice (angl. <em>tuple</em>) hodnot.\nFunguje podobn&#x11B; jako seznam, ale nedaj&#xED; se do n&#xED; p&#x159;id&#xE1;vat prvky, nebo odeb&#xED;rat\na jinak m&#x11B;nit.\nKdy&#x17E; m&#xE1;m trojici, v&#x17E;dycky z&#x16F;stane jako trojice.</p>\n<p>Kdy&#x17E; m&#xE1;&#x161; <var>n</var>-tici, m&#x16F;&#x17E;e&#x161; ji p&#x159;i&#x159;azen&#xED;m <em>rozbalit</em> (angl. <em>unpack</em>)\ndo n&#x11B;kolika prom&#x11B;nn&#xFD;ch:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">podil</span><span class=\"p\">,</span> <span class=\"n\">zbytek</span> <span class=\"o\">=</span> <span class=\"n\">podil_a_zbytek</span><span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">podil</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">zbytek</span><span class=\"p\">)</span>\n</pre></div><p><var>N</var>-tice maj&#xED; spoustu vyu&#x17E;it&#xED;, nap&#x159;&#xED;klad:</p>\n<ul>\n<li>Bod v prostoru m&#xE1; 3 sou&#x159;adnice &#x2013; trojice &#x10D;&#xED;sel!</li>\n<li>Hrac&#xED; karta m&#xE1; barvu a hodotu &#x2013; dvojice &#x10D;&#xED;sla a &#x159;et&#x11B;zce, nap&#x159;. <code>(2, &apos;piky&apos;)</code></li>\n</ul>\n<p>Ob&#x10D;as je pot&#x159;eba d&#xE1;t <var>n</var>-tice do seznamu, nap&#x159;. abys ulo&#x17E;il/a\ninformace o cel&#xE9;m bal&#xED;&#x10D;ku hrac&#xED;ch karet.\nV&#xA0;podobn&#xFD;ch p&#x159;&#xED;padech je pot&#x159;eba ka&#x17E;dou <var>n</var>-tici uzav&#x159;&#xED;t do z&#xE1;vorek,\naby bylo jasn&#xE9; kde za&#x10D;&#xED;n&#xE1; a kde kon&#x10D;&#xED;.\nTady je seznam dvojic:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">ruka</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"s1\">&apos;piky&apos;</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"s1\">&apos;k&#x159;&#xED;&#x17E;e&apos;</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">8</span><span class=\"p\">,</span> <span class=\"s1\">&apos;k&#xE1;ry&apos;</span><span class=\"p\">)]</span>\n</pre></div><p>Kdy&#x17E; takov&#xFD; seznam m&#xE1;&#x161;, m&#x16F;&#x17E;e&#x161; ho proj&#xED;t v&#xA0;cyklu <code>for</code> s&#xA0;pomoc&#xED; rozbalov&#xE1;n&#xED;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">for</span> <span class=\"n\">hodnota</span><span class=\"p\">,</span> <span class=\"n\">barva</span> <span class=\"ow\">in</span> <span class=\"n\">ruka</span><span class=\"p\">:</span>\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Hraju&apos;</span><span class=\"p\">,</span> <span class=\"n\">hodnota</span><span class=\"p\">,</span> <span class=\"s1\">&apos;a jsou to&apos;</span><span class=\"p\">,</span> <span class=\"n\">barva</span><span class=\"p\">)</span>\n</pre></div><h2>Zip</h2>\n<p><var>N</var>-tice, respektive sekvenci <var>n</var>-tic vrac&#xED; funkce <code>zip</code>,\nkter&#xE1; umo&#x17E;&#x148;uje proj&#xED;t z&#xE1;rove&#x148; n&#x11B;kolik seznam&#x16F;,\njejich&#x17E; prvky si navz&#xE1;jem odpov&#xED;daj&#xED;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">veci</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&apos;tr&#xE1;va&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;slunce&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;mrkev&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;&#x159;eka&apos;</span><span class=\"p\">]</span>\n<span class=\"n\">barvy</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&apos;zelen&#xE1;&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;&#x17E;lut&#xE9;&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;oran&#x17E;ov&#xE1;&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;modr&#xE1;&apos;</span><span class=\"p\">]</span>\n<span class=\"n\">mista</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">&apos;na zemi&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;naho&#x159;e&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;na tal&#xED;&#x159;i&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;za z&#xED;dkou&apos;</span><span class=\"p\">]</span>\n\n<span class=\"k\">for</span> <span class=\"n\">vec</span><span class=\"p\">,</span> <span class=\"n\">barva</span><span class=\"p\">,</span> <span class=\"n\">misto</span> <span class=\"ow\">in</span> <span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"n\">veci</span><span class=\"p\">,</span> <span class=\"n\">barvy</span><span class=\"p\">,</span> <span class=\"n\">mista</span><span class=\"p\">):</span>\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">barva</span><span class=\"p\">,</span> <span class=\"n\">vec</span><span class=\"p\">,</span> <span class=\"s1\">&apos;je&apos;</span><span class=\"p\">,</span> <span class=\"n\">misto</span><span class=\"p\">)</span>\n</pre></div>\n\n\n        "
    }
  }
}