Řetězcové funkce a metody

Řetězce umí všelijaké triky. Funkcí len() můžeš zjistit, jak je řetězec dlouhý; operátorem in pak jestli v sobě obsahuje daný podřetězec.

Zápis Popis Příklad
len(r) Délka řetězce len('čokoláda')
x in r True pokud je řetězec x obsažen v r 'oko' in 'čokoláda'
x not in r Opak x in r 'dub' not in 'čokoláda

Řetězce vždy berou v potaz velikost písmen, takže např. 'ČOKO' in 'čokoláda' je False. Kdybys chtěla porovnávat bez ohledu na velikost písmen, musela bys oba řetězce převést třeba na malá písmena a pak je porovnat.

A jak se převádí na malá písmena? K tomu budeme potřebovat další novou vlastnost Pythonu: metody.

Metody

Metoda (angl. method) je jako funkce – něco, co se dá zavolat. Na rozdíl od funkce je svázaná s nějakým objektem (hodnotou). Volá se tak, že se za objekt napíše tečka, za ní jméno metody a za to celé se, jako u funkcí, připojí závorky s případnými argumenty.

Řetězcové metody upper() a lower() převádí text na velká, respektive malá písmena. Zkus si to!

retezec = 'Ahoj'
print(retezec.upper())
print(retezec.lower())
print(retezec)

Všimni si, že původní řetězec se nemění; metoda vrátí nový řetězec, ten starý zůstává.

To je obecná vlastnost řetězců v Pythonu: jednou existující řetězec se už nedá změnit, dá se jen vytvořit nějaký odvozený.

Iniciály

Pro procvičení metod a vybírání znaků si zkus napsat program, který se zeptá na jméno, pak na příjmení a pak vypíše iniciály – první písmena zadaných jmen.

Iniciály jsou vždycky velkými písmeny (i kdyby byl uživatel líný mačkat Shift).

Řešení

Řetězcových metod je celá řada. Nejužitečnější z nich najdeš v taháku, který si můžeš stáhnout či vytisknout.

A úplně všechny řetězcové metody jsou popsány v dokumentaci Pythonu (anglicky; plné věcí, které ještě neznáš).

Všimni si, že len není metoda, ale funkce; píše se len(r), ne r.len(). Proč tomu tak je, to za nějakou dobu poznáš.

Metoda format

Pro úplnost: občas uvidíš metoda format, která doplní do šablony podobné jako u formátovacích řetězců (f'...').

sablona = '{a}×{b} je {vysledek}'
vypis = sablona.format(vysledek=3 * 4, a=3, b=4)
print(vypis)

Funguje i zkrácený zápis, kdy necháš závorky prázdné a argumenty nepojmenuješ:

vypis = 'Ahoj {}! Výsledek je {}.'.format('Elvíro', 7)
print(vypis)

Cvičení

Zkus napsat funkci zamen(retezec, pozice, znak).

Tato funkce vrátí řetězec, který má na dané pozici daný znak; jinak je stejný jako původní retezec. Například:

# Zaměň třetí znak ve slově "čokoláda"
print(zamen('čokoláda', 3, 'u'))   # → čokuláda

Pozor na to, že řetězce v Pythonu nelze měnit. Musíš vytvořit nový řetězec poskládaný z částí toho starého.

Řešení

{
  "data": {
    "sessionMaterial": {
      "id": "session-material:2019/brno-podzim-pondeli:turtle:3",
      "title": "Řetězcové funkce a metody",
      "html": "\n          \n    \n\n    <h1>&#x158;et&#x11B;zcov&#xE9; funkce a metody</h1>\n<p>&#x158;et&#x11B;zce um&#xED; v&#x161;elijak&#xE9; triky.\nFunkc&#xED; <code>len()</code> m&#x16F;&#x17E;e&#x161; zjistit, jak je &#x159;et&#x11B;zec dlouh&#xFD;;\noper&#xE1;torem <code>in</code> pak jestli v sob&#x11B; obsahuje dan&#xFD; pod&#x159;et&#x11B;zec.</p>\n<table class=\"table\">\n    <tbody><tr>\n        <th>Z&#xE1;pis</th>\n        <th>Popis</th>\n        <th>P&#x159;&#xED;klad</th>\n    </tr>\n    <tr>\n        <td><code>len(r)</code></td>\n        <td>D&#xE9;lka &#x159;et&#x11B;zce</td>\n        <td><code>len(&apos;&#x10D;okol&#xE1;da&apos;)</code></td>\n    </tr>\n    <tr>\n        <td><code>x&#xA0;in&#xA0;r</code></td>\n        <td>True pokud je &#x159;et&#x11B;zec <code>x</code> obsa&#x17E;en v <code>r</code></td>\n        <td><code>&apos;oko&apos; in &apos;&#x10D;okol&#xE1;da&apos;</code></td>\n    </tr>\n    <tr>\n        <td><code>x&#xA0;not&#xA0;in&#xA0;r</code></td>\n        <td>Opak <code>x in r</code></td>\n        <td><code>&apos;dub&apos; not in &apos;&#x10D;okol&#xE1;da</code></td>\n    </tr>\n</tbody></table><p>&#x158;et&#x11B;zce v&#x17E;dy berou v potaz velikost p&#xED;smen,\ntak&#x17E;e nap&#x159;. <code>&apos;&#x10C;OKO&apos; in &apos;&#x10D;okol&#xE1;da&apos;</code> je <code>False</code>.\nKdybys cht&#x11B;la porovn&#xE1;vat bez ohledu na velikost p&#xED;smen,\nmusela bys oba &#x159;et&#x11B;zce p&#x159;ev&#xE9;st t&#x159;eba na mal&#xE1; p&#xED;smena\na pak je porovnat.</p>\n<p>A jak se p&#x159;ev&#xE1;d&#xED; na mal&#xE1; p&#xED;smena?\nK tomu budeme pot&#x159;ebovat dal&#x161;&#xED; novou vlastnost Pythonu: metody.</p>\n<h2>Metody</h2>\n<p><em>Metoda</em> (angl. <em>method</em>) je jako funkce &#x2013; n&#x11B;co, co se d&#xE1; zavolat.\nNa rozd&#xED;l od funkce je sv&#xE1;zan&#xE1; s n&#x11B;jak&#xFD;m <em>objektem</em> (hodnotou).\nVol&#xE1; se tak, &#x17E;e se za objekt nap&#xED;&#x161;e te&#x10D;ka,\nza n&#xED; jm&#xE9;no metody a za to cel&#xE9; se, jako u funkc&#xED;, p&#x159;ipoj&#xED; z&#xE1;vorky\ns&#xA0;p&#x159;&#xED;padn&#xFD;mi argumenty.</p>\n<p>&#x158;et&#x11B;zcov&#xE9; metody <code>upper()</code> a <code>lower()</code>\np&#x159;ev&#xE1;d&#xED; text na velk&#xE1;, respektive mal&#xE1; p&#xED;smena.\nZkus si to!</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">retezec</span> <span class=\"o\">=</span> <span class=\"s1\">&apos;Ahoj&apos;</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">retezec</span><span class=\"o\">.</span><span class=\"n\">upper</span><span class=\"p\">())</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">retezec</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">())</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">retezec</span><span class=\"p\">)</span>\n</pre></div><div class=\"admonition note\"><p>V&#x161;imni si, &#x17E;e p&#x16F;vodn&#xED; &#x159;et&#x11B;zec se nem&#x11B;n&#xED;; metoda vr&#xE1;t&#xED; nov&#xFD; &#x159;et&#x11B;zec, ten\nstar&#xFD; z&#x16F;st&#xE1;v&#xE1;.</p>\n<p>To je obecn&#xE1; vlastnost &#x159;et&#x11B;zc&#x16F; v&#xA0;Pythonu: jednou existuj&#xED;c&#xED; &#x159;et&#x11B;zec se u&#x17E;\nned&#xE1; zm&#x11B;nit, d&#xE1; se jen vytvo&#x159;it n&#x11B;jak&#xFD; odvozen&#xFD;.</p>\n</div><h3>Inici&#xE1;ly</h3>\n<p>Pro procvi&#x10D;en&#xED; metod a vyb&#xED;r&#xE1;n&#xED; znak&#x16F; si zkus napsat program,\nkter&#xFD; se zept&#xE1; na jm&#xE9;no, pak na p&#x159;&#xED;jmen&#xED;\na pak vyp&#xED;&#x161;e inici&#xE1;ly &#x2013; prvn&#xED; p&#xED;smena zadan&#xFD;ch jmen.</p>\n<p>Inici&#xE1;ly jsou v&#x17E;dycky velk&#xFD;mi p&#xED;smeny\n(i kdyby byl u&#x17E;ivatel l&#xED;n&#xFD; ma&#x10D;kat Shift).</p>\n<div class=\"solution\" id=\"solution-0\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2019/brno-podzim-pondeli/beginners/str-methods/index/solutions/0/\"><span class=\"link-text\">Uk&#xE1;zat &#x159;e&#x161;en&#xED;</span></a>\n    </div>\n    <div class=\"solution-body\" aria-hidden=\"true\">\n        <div class=\"highlight\"><pre><span></span><span class=\"n\">jmeno</span> <span class=\"o\">=</span> <span class=\"nb\">input</span><span class=\"p\">(</span><span class=\"s1\">&apos;Zadej jm&#xE9;no: &apos;</span><span class=\"p\">)</span>\n<span class=\"n\">prijmeni</span> <span class=\"o\">=</span> <span class=\"nb\">input</span><span class=\"p\">(</span><span class=\"s1\">&apos;Zadej p&#x159;&#xED;jmen&#xED; &apos;</span><span class=\"p\">)</span>\n<span class=\"n\">inicialy</span> <span class=\"o\">=</span> <span class=\"n\">jmeno</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">prijmeni</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Inici&#xE1;ly:&apos;</span><span class=\"p\">,</span> <span class=\"n\">inicialy</span><span class=\"o\">.</span><span class=\"n\">upper</span><span class=\"p\">())</span>\n</pre></div><p>Zp&#x16F;sob&#x16F;, jak takov&#xFD; program napsat, je v&#xED;ce.\nLze nap&#x159;&#xED;klad zavolat <code>upper()</code> dvakr&#xE1;t &#x2013; zvl&#xE1;&#x161;&#x165; na jm&#xE9;no a zvl&#xE1;&#x161;&#x165; na p&#x159;&#xED;jmen&#xED;.</p>\n<p>Nebo to jde zapsat i takto &#x2013;\nmetoda se d&#xE1; volat na v&#xFD;sledku jak&#xE9;hokoli v&#xFD;razu:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">jmeno</span> <span class=\"o\">=</span> <span class=\"nb\">input</span><span class=\"p\">(</span><span class=\"s1\">&apos;Zadej jm&#xE9;no: &apos;</span><span class=\"p\">)</span>\n<span class=\"n\">prijmeni</span> <span class=\"o\">=</span> <span class=\"nb\">input</span><span class=\"p\">(</span><span class=\"s1\">&apos;Zadej p&#x159;&#xED;jmen&#xED; &apos;</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Inici&#xE1;ly:&apos;</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">jmeno</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">prijmeni</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span><span class=\"o\">.</span><span class=\"n\">upper</span><span class=\"p\">())</span>\n</pre></div><p>Doporu&#x10D;uji sp&#xED;&#x161; prvn&#xED; zp&#x16F;sob, ten se smyslupln&#xFD;mi n&#xE1;zvy prom&#x11B;nn&#xFD;ch.\nJe sice del&#x161;&#xED;, ale mnohem p&#x159;ehledn&#x11B;j&#x161;&#xED;.</p>\n    </div>\n</div><p>&#x158;et&#x11B;zcov&#xFD;ch metod je cel&#xE1; &#x159;ada.\nNeju&#x17E;ite&#x10D;n&#x11B;j&#x161;&#xED; z&#xA0;nich najde&#x161; v&#xA0;<a href=\"https://pyvec.github.io/cheatsheets/strings/strings-cs.pdf\">tah&#xE1;ku</a>, kter&#xFD; si m&#x16F;&#x17E;e&#x161; st&#xE1;hnout &#x10D;i vytisknout.</p>\n<p>A &#xFA;pln&#x11B; v&#x161;echny &#x159;et&#x11B;zcov&#xE9; metody jsou pops&#xE1;ny v&#xA0;<a href=\"https://docs.python.org/3/library/stdtypes.html#string-methods\">dokumentaci Pythonu</a> (anglicky; pln&#xE9; v&#x11B;c&#xED;, kter&#xE9; je&#x161;t&#x11B; nezn&#xE1;&#x161;).</p>\n<p>V&#x161;imni si, &#x17E;e <code>len</code> nen&#xED; metoda, ale funkce; p&#xED;&#x161;e se <code>len(r)</code>, ne <code>r.len()</code>.\nPro&#x10D; tomu tak je, to za n&#x11B;jakou dobu pozn&#xE1;&#x161;.</p>\n<h2>Metoda format</h2>\n<p>Pro &#xFA;plnost: ob&#x10D;as uvid&#xED;&#x161; metoda <code>format</code>, kter&#xE1; dopln&#xED; do &#x161;ablony\npodobn&#xE9; jako u form&#xE1;tovac&#xED;ch &#x159;et&#x11B;zc&#x16F; (<code>f&apos;...&apos;</code>).</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">sablona</span> <span class=\"o\">=</span> <span class=\"s1\">&apos;{a}&#xD7;{b} je {vysledek}&apos;</span>\n<span class=\"n\">vypis</span> <span class=\"o\">=</span> <span class=\"n\">sablona</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"n\">vysledek</span><span class=\"o\">=</span><span class=\"mi\">3</span> <span class=\"o\">*</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"n\">a</span><span class=\"o\">=</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"o\">=</span><span class=\"mi\">4</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">vypis</span><span class=\"p\">)</span>\n</pre></div><p>Funguje i zkr&#xE1;cen&#xFD; z&#xE1;pis, kdy nech&#xE1;&#x161; z&#xE1;vorky pr&#xE1;zdn&#xE9; a argumenty nepojmenuje&#x161;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">vypis</span> <span class=\"o\">=</span> <span class=\"s1\">&apos;Ahoj {}! V&#xFD;sledek je {}.&apos;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"s1\">&apos;Elv&#xED;ro&apos;</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">vypis</span><span class=\"p\">)</span>\n</pre></div><h2>Cvi&#x10D;en&#xED;</h2>\n<p>Zkus napsat funkci <code>zamen(retezec, pozice, znak)</code>.</p>\n<p>Tato funkce vr&#xE1;t&#xED; &#x159;et&#x11B;zec, kter&#xFD; m&#xE1; na dan&#xE9; pozici\ndan&#xFD; znak; jinak je stejn&#xFD; jako p&#x16F;vodn&#xED; <code>retezec</code>. Nap&#x159;&#xED;klad:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"c1\"># Zam&#x11B;&#x148; t&#x159;et&#xED; znak ve slov&#x11B; &quot;&#x10D;okol&#xE1;da&quot;</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">zamen</span><span class=\"p\">(</span><span class=\"s1\">&apos;&#x10D;okol&#xE1;da&apos;</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"s1\">&apos;u&apos;</span><span class=\"p\">))</span>   <span class=\"c1\"># &#x2192; &#x10D;okul&#xE1;da</span>\n</pre></div><p>Pozor na to, &#x17E;e &#x159;et&#x11B;zce v&#xA0;Pythonu nelze m&#x11B;nit.\nMus&#xED;&#x161; vytvo&#x159;it nov&#xFD; &#x159;et&#x11B;zec poskl&#xE1;dan&#xFD; z &#x10D;&#xE1;st&#xED; toho star&#xE9;ho.</p>\n<div class=\"solution\" id=\"solution-1\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2019/brno-podzim-pondeli/beginners/str-methods/index/solutions/1/\"><span class=\"link-text\">Uk&#xE1;zat &#x159;e&#x161;en&#xED;</span></a>\n    </div>\n    <div class=\"solution-body\" aria-hidden=\"true\">\n        <div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">zamen</span><span class=\"p\">(</span><span class=\"n\">retezec</span><span class=\"p\">,</span> <span class=\"n\">pozice</span><span class=\"p\">,</span> <span class=\"n\">znak</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Zam&#x11B;n&#xED; znak na dan&#xE9; pozici</span>\n\n<span class=\"sd\">    Vr&#xE1;t&#xED; &#x159;et&#x11B;zec, kter&#xFD; m&#xE1; na dan&#xE9; pozici dan&#xFD; znak;</span>\n<span class=\"sd\">    jinak je stejn&#xFD; jako vstupn&#xED; retezec</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">retezec</span><span class=\"p\">[:</span><span class=\"n\">pozice</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">znak</span> <span class=\"o\">+</span> <span class=\"n\">retezec</span><span class=\"p\">[</span><span class=\"n\">pozice</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">:]</span>\n</pre></div>\n    </div>\n</div>\n\n\n        "
    }
  }
}