Range – sekvence čísel

Funkce range(10) vrátí speciální hodnotu, která v sobě obsahuje čísla od 0 do 9:

>>> sekvence = range(10)
>>> sekvence
range(0, 10)

Je to hodnota typu range, podobně jako čísla jsou typu int, řetězce typu str, nebo seznamy typu list.

Chceš-li se podívat, co v tomhle range(0, 10) vlastně je, máš dvě základní možnosti – projít ho cyklem for nebo převést na seznam konkrétních čísel:

>>> sekvence
range(0, 10)
>>> for i in sekvence:
...     print(i)
0
1
2
3
4
5
6
7
8
9
>>> list(sekvence)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Možná se ptáš – proč tak složitě? Proč se místo range(0, 10) prostě ta čísla neukážou rovnou?

Je to proto, že range se dá použít na opravdu dlouhé řady čísel:

>>> range(10000)
range(0, 10000)
>>> list(range(10000))
[0, 1, 2, 3, ..., 9999]

Kdybys zkusila třeba list(range(1000000000000000000)), počítači dojde paměť. Miliarda čísel se tam prostě nevejde. Python vyhodí výjimku MemoryError. Se samotným range(1000000000000000000) ale není problém. S konceptem čísel od 0 do miliardy se počítač vypořádá, i když si je neumí „zapamatovat“ všechny najednou.

Je spousta věcí, které Python umí s range udělat, aniž by potřeboval „spočítat“ každé z čísel. Spousta operací, které znáš od seznamů, bude fungovat i s range:

>>> zajimava_cisla = range(8, 10000, 3)  # Každé třetí číslo od 8 do 9999
>>> zajimava_cisla[80]          # Osmdesáté "zajímavé číslo"
248
>>> zajimava_cisla[:5]          # Prvních 5 "zajímavých čísel"
range(8, 23, 3)
>>> list(zajimava_cisla[:5])    # Vypsání prvních 5 "zajímavých čísel"
[8, 11, 14, 17, 20]
>>> len(zajimava_cisla)         # Kolik tam je čísel?
3331
>>> 1337 in zajimava_cisla      # Je v této sekvenci moje konkrétní číslo ?
True
>>> zajimava_cisla.index(1337)  # Kolikáté je?
443
>>> import random
>>> random.choice(zajimava_cisla)
1229
>>> for i in zajimava_cisla:
...     print(i)
...     if i > 20:
...         break  # Stačilo!
8
11
14
17
20
23

Objekt range ale nejde měnit – metody jako zajimava_cisla.sort(), zajimava_cisla.pop() fungovat nebudou.

{
  "data": {
    "sessionMaterial": {
      "id": "session-material:2019/brno-jaro-2019-pondeli:solitaire:0",
      "title": "Range - sekvence čísel",
      "html": "\n          \n    \n\n    <h1>Range &#x2013; sekvence &#x10D;&#xED;sel</h1>\n<p>Funkce <code>range(10)</code> vr&#xE1;t&#xED; speci&#xE1;ln&#xED; hodnotu,\nkter&#xE1; v sob&#x11B; obsahuje &#x10D;&#xED;sla od 0 do 9:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">sekvence</span> <span class=\"o\">=</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">sekvence</span>\n<span class=\"go\">range(0, 10)</span>\n</pre></div><p>Je to hodnota typu <code>range</code>, podobn&#x11B; jako &#x10D;&#xED;sla jsou typu <code>int</code>, &#x159;et&#x11B;zce typu\n<code>str</code>, nebo seznamy typu <code>list</code>.</p>\n<p>Chce&#x161;-li se pod&#xED;vat, co v&#xA0;tomhle <code>range(0, 10)</code> vlastn&#x11B; je, m&#xE1;&#x161; dv&#x11B; z&#xE1;kladn&#xED;\nmo&#x17E;nosti &#x2013; proj&#xED;t ho cyklem <code>for</code> nebo p&#x159;ev&#xE9;st na seznam konkr&#xE9;tn&#xED;ch &#x10D;&#xED;sel:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">sekvence</span>\n<span class=\"go\">range(0, 10)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"n\">sekvence</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">)</span>\n<span class=\"go\">0</span>\n<span class=\"go\">1</span>\n<span class=\"go\">2</span>\n<span class=\"go\">3</span>\n<span class=\"go\">4</span>\n<span class=\"go\">5</span>\n<span class=\"go\">6</span>\n<span class=\"go\">7</span>\n<span class=\"go\">8</span>\n<span class=\"go\">9</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">sekvence</span><span class=\"p\">)</span>\n<span class=\"go\">[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</span>\n</pre></div><p>Mo&#x17E;n&#xE1; se pt&#xE1;&#x161; &#x2013; pro&#x10D; tak slo&#x17E;it&#x11B;?\nPro&#x10D; se m&#xED;sto <code>range(0, 10)</code> prost&#x11B; ta &#x10D;&#xED;sla neuk&#xE1;&#x17E;ou rovnou?</p>\n<p>Je to proto, &#x17E;e <code>range</code> se d&#xE1; pou&#x17E;&#xED;t na opravdu dlouh&#xE9; &#x159;ady &#x10D;&#xED;sel:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">10000</span><span class=\"p\">)</span>\n<span class=\"go\">range(0, 10000)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">10000</span><span class=\"p\">))</span>\n<span class=\"go\">[0, 1, 2, 3, ..., 9999]</span>\n</pre></div><p>Kdybys zkusila t&#x159;eba <code>list(range(1000000000000000000))</code>, po&#x10D;&#xED;ta&#x10D;i\ndojde pam&#x11B;&#x165;.\nMiliarda &#x10D;&#xED;sel se tam prost&#x11B; nevejde.\nPython vyhod&#xED; v&#xFD;jimku  <code>MemoryError</code>.\nSe samotn&#xFD;m <code>range(1000000000000000000)</code> ale nen&#xED; probl&#xE9;m.\nS&#xA0;konceptem &#x10D;&#xED;sel od 0 do miliardy se po&#x10D;&#xED;ta&#x10D; vypo&#x159;&#xE1;d&#xE1;, i kdy&#x17E; si je neum&#xED;\n&#x201E;zapamatovat&#x201C; v&#x161;echny <em>najednou</em>.</p>\n<p>Je spousta v&#x11B;c&#xED;, kter&#xE9; Python um&#xED; s&#xA0;<code>range</code> ud&#x11B;lat, ani&#x17E; by pot&#x159;eboval\n&#x201E;spo&#x10D;&#xED;tat&#x201C; ka&#x17E;d&#xE9; z&#xA0;&#x10D;&#xED;sel.\nSpousta operac&#xED;, kter&#xE9; zn&#xE1;&#x161; od seznam&#x16F;, bude fungovat i s&#xA0;<code>range</code>:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">zajimava_cisla</span> <span class=\"o\">=</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">8</span><span class=\"p\">,</span> <span class=\"mi\">10000</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">)</span>  <span class=\"c1\"># Ka&#x17E;d&#xE9; t&#x159;et&#xED; &#x10D;&#xED;slo od 8 do 9999</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">zajimava_cisla</span><span class=\"p\">[</span><span class=\"mi\">80</span><span class=\"p\">]</span>          <span class=\"c1\"># Osmdes&#xE1;t&#xE9; &quot;zaj&#xED;mav&#xE9; &#x10D;&#xED;slo&quot;</span>\n<span class=\"go\">248</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">zajimava_cisla</span><span class=\"p\">[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>          <span class=\"c1\"># Prvn&#xED;ch 5 &quot;zaj&#xED;mav&#xFD;ch &#x10D;&#xED;sel&quot;</span>\n<span class=\"go\">range(8, 23, 3)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">zajimava_cisla</span><span class=\"p\">[:</span><span class=\"mi\">5</span><span class=\"p\">])</span>    <span class=\"c1\"># Vyps&#xE1;n&#xED; prvn&#xED;ch 5 &quot;zaj&#xED;mav&#xFD;ch &#x10D;&#xED;sel&quot;</span>\n<span class=\"go\">[8, 11, 14, 17, 20]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">zajimava_cisla</span><span class=\"p\">)</span>         <span class=\"c1\"># Kolik tam je &#x10D;&#xED;sel?</span>\n<span class=\"go\">3331</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"mi\">1337</span> <span class=\"ow\">in</span> <span class=\"n\">zajimava_cisla</span>      <span class=\"c1\"># Je v t&#xE9;to sekvenci moje konkr&#xE9;tn&#xED; &#x10D;&#xED;slo ?</span>\n<span class=\"go\">True</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">zajimava_cisla</span><span class=\"o\">.</span><span class=\"n\">index</span><span class=\"p\">(</span><span class=\"mi\">1337</span><span class=\"p\">)</span>  <span class=\"c1\"># Kolik&#xE1;t&#xE9; je?</span>\n<span class=\"go\">443</span>\n</pre></div><div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span> <span class=\"nn\">random</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">random</span><span class=\"o\">.</span><span class=\"n\">choice</span><span class=\"p\">(</span><span class=\"n\">zajimava_cisla</span><span class=\"p\">)</span>\n<span class=\"go\">1229</span>\n</pre></div><div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"n\">zajimava_cisla</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>    <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">&gt;</span> <span class=\"mi\">20</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>        <span class=\"k\">break</span>  <span class=\"c1\"># Sta&#x10D;ilo!</span>\n<span class=\"go\">8</span>\n<span class=\"go\">11</span>\n<span class=\"go\">14</span>\n<span class=\"go\">17</span>\n<span class=\"go\">20</span>\n<span class=\"go\">23</span>\n</pre></div><p>Objekt <code>range</code> ale nejde m&#x11B;nit &#x2013; metody jako <code>zajimava_cisla.sort()</code>,\n<code>zajimava_cisla.pop()</code> fungovat nebudou.</p>\n\n\n        "
    }
  }
}