portal Michała Hanćkowiaka
Begin main content
{
"cells": [
  {
  "cell_type": "markdown",
  "id": "d6cabf5f-8469-4a8b-bfbc-d3a2bcf39c7e",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "<div class=\"alert alert-block\" style=\"text-align: center; background-color: lightgrey; font-weight: bold;\">\n",
    "<h1> Algorytmy i programowanie</h1>\n",
    "<h2> <i>Krotki, zbiory i słowniki w Pythonie</i></h2> \n",
    "<h3></h3>\n",
    "</div>"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "803b4bbb-d608-49dd-87be-96045723f0bd",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "### Krotki\n",
    "\n",
    "Krotka (*ang. tuple*), podobnie jak lista, jest uporządkowaną sekwencją wartości dowolnego typu, które są indeksowane liczbami całkowitymi począwszy od 0. Jednak w odróżnieniu od listy raz zadeklarowana krotka jest niemodyfikowalna tzn. nie można zmieniać wartości jej elementów, ani dodawać lub usuwać jej elementów. Krotkę definiuje się za pomocą wymienienia jej elementów oddzielonych przecinkami i umieszczonych w zwykłych nawiasach (nawiasy okrągłe są pomijalne)."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 3,
  "id": "24596060-da1f-4faa-ab33-07dea70727ec",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "('kuchnia', 'łazienka', 'sypialnia', 'sypialnia', 'jadalnia', 'salon')\n"
    ]
    }
  ],
  "source": [
    "dom = (\"kuchnia\", \"łazienka\", \"sypialnia\", \"sypialnia\", \"jadalnia\", \"salon\")      # nawiasy nie są konieczne\n",
    "print(dom)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "9f221245-f28c-43dc-a981-25cae463a58e",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Większość operacji jakie można wykonać na listach można również wykonywać na krotkach. Oczywiście z wyjątkiem tych, które próbują modyfikować elementy krotki."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 4,
  "id": "a2685706-712d-41f4-87bd-b3d6eb719359",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "(1, 2, 3, 5, 6)\n",
      "(0, 1, 0, 1, 0, 1)\n",
      "('sypialnia', 'sypialnia')\n"
    ]
    }
  ],
  "source": [
    "print((1, 2, 3) + (5, 6))    # dodawanie krotek\n",
    "print((0, 1) * 3)            # mnożenie krotki przez liczbę odpowiada powielaniu krotki\n",
    "print(dom[2:-2])              # wycinanie"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "3b21e7da-5ed6-4de3-b669-060cb3881ec2",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Jak już zostało wspomniane, krotek nie można modyfikować. Jeśli jednak z jakiegoś powodu chcemy ją zmodyfikować to możemy utworzyć nową krotkę, która zastąpi tę starą lub możemy też przekonwertować krotkę na listę, którą można już modyfikować, a następnie przekonwertować ją z powrotem na krotkę (w tym celu należy użyć kolejno funkcji `list()` oraz `tuple()`)."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 5,
  "id": "748cb5cf-ed6a-44b6-86bb-b8a9762a3acb",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "salon\n"
    ]
    },
    {
    "ename": "TypeError",
    "evalue": "'tuple' object does not support item assignment",
    "output_type": "error",
    "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[5], line 3\u001b[0m\n\u001b[1;32m      1\u001b[0m dom \u001b[38;5;241m=\u001b[39m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mkuchnia\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124młazienka\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msypialnia\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msypialnia\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mjadalnia\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msalon\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m      2\u001b[0m \u001b[38;5;28mprint\u001b[39m(dom[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m])\n\u001b[0;32m----> 3\u001b[0m \u001b[43mdom\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mkuchnia mała\u001b[39m\u001b[38;5;124m\"\u001b[39m\n",
      "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
    ]
    }
  ],
  "source": [
    "dom = (\"kuchnia\", \"łazienka\", \"sypialnia\", \"sypialnia\", \"jadalnia\", \"salon\")\n",
    "print(dom[-1])\n",
    "dom[0] = \"kuchnia mała\""
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 6,
  "id": "fd77fe07-b083-4a07-9997-27c14f76b648",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "Help on class tuple in module builtins:\n",
      "\n",
      "class tuple(object)\n",
      " |  tuple(iterable=(), /)\n",
      " |  \n",
      " |  Built-in immutable sequence.\n",
      " |  \n",
      " |  If no argument is given, the constructor returns an empty tuple.\n",
      " |  If iterable is specified the tuple is initialized from iterable's items.\n",
      " |  \n",
      " |  If the argument is a tuple, the return value is the same object.\n",
      " |  \n",
      " |  Built-in subclasses:\n",
      " |      asyncgen_hooks\n",
      " |      UnraisableHookArgs\n",
      " |  \n",
      " |  Methods defined here:\n",
      " |  \n",
      " |  __add__(self, value, /)\n",
      " |      Return self+value.\n",
      " |  \n",
      " |  __contains__(self, key, /)\n",
      " |      Return key in self.\n",
      " |  \n",
      " |  __eq__(self, value, /)\n",
      " |      Return self==value.\n",
      " |  \n",
      " |  __ge__(self, value, /)\n",
      " |      Return self>=value.\n",
      " |  \n",
      " |  __getattribute__(self, name, /)\n",
      " |      Return getattr(self, name).\n",
      " |  \n",
      " |  __getitem__(self, key, /)\n",
      " |      Return self[key].\n",
      " |  \n",
      " |  __getnewargs__(self, /)\n",
      " |  \n",
      " |  __gt__(self, value, /)\n",
      " |      Return self>value.\n",
      " |  \n",
      " |  __hash__(self, /)\n",
      " |      Return hash(self).\n",
      " |  \n",
      " |  __iter__(self, /)\n",
      " |      Implement iter(self).\n",
      " |  \n",
      " |  __le__(self, value, /)\n",
      " |      Return self<=value.\n",
      " |  \n",
      " |  __len__(self, /)\n",
      " |      Return len(self).\n",
      " |  \n",
      " |  __lt__(self, value, /)\n",
      " |      Return self<value.\n",
      " |  \n",
      " |  __mul__(self, value, /)\n",
      " |      Return self*value.\n",
      " |  \n",
      " |  __ne__(self, value, /)\n",
      " |      Return self!=value.\n",
      " |  \n",
      " |  __repr__(self, /)\n",
      " |      Return repr(self).\n",
      " |  \n",
      " |  __rmul__(self, value, /)\n",
      " |      Return value*self.\n",
      " |  \n",
      " |  count(self, value, /)\n",
      " |      Return number of occurrences of value.\n",
      " |  \n",
      " |  index(self, value, start=0, stop=9223372036854775807, /)\n",
      " |      Return first index of value.\n",
      " |      \n",
      " |      Raises ValueError if the value is not present.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Class methods defined here:\n",
      " |  \n",
      " |  __class_getitem__(...) from builtins.type\n",
      " |      See PEP 585\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Static methods defined here:\n",
      " |  \n",
      " |  __new__(*args, **kwargs) from builtins.type\n",
      " |      Create and return a new object.  See help(type) for accurate signature.\n",
      "\n"
    ]
    }
  ],
  "source": [
    "help(tuple)"
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 7,
  "id": "dacc8021-926c-45ab-8168-c19bea1b0df8",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "('kuchnia', 'łazienka', 'sypialnia', 'sypialnia', 'jadalnia', 'salon', 'garaż')\n"
    ]
    }
  ],
  "source": [
    "dom = (\"kuchnia\", \"łazienka\", \"sypialnia\", \"sypialnia\", \"jadalnia\", \"salon\")\n",
    "dodatkowe_pomieszczenie = (\"garaż\",)              # tak definiuje się pojedynczą krotkę (zwróć uwagę na przecinek)\n",
    "dom_nowy = dom + dodatkowe_pomieszczenie\n",
    "dom = dom_nowy\n",
    "print(dom)"
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 8,
  "id": "20403243-0784-44e3-9dcf-9045d7847247",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "('łazienka', 'sypialnia', 'sypialnia', 'jadalnia', 'salon z kuchnią', 'garaż')\n"
    ]
    }
  ],
  "source": [
    "dom = (\"kuchnia\", \"łazienka\", \"sypialnia\", \"sypialnia\", \"jadalnia\", \"salon\")\n",
    "dom_lista = list(dom)\n",
    "dom_lista[-1] = \"salon z kuchnią\"\n",
    "dom_lista.append(\"garaż\")\n",
    "dom_lista.remove(\"kuchnia\")\n",
    "dom = tuple(dom_lista)\n",
    "print(dom)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "ceed9818-9248-4197-a6ff-2ce7f7ccda9f",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "W języku Python istnieje również bardzo wygodny sposób przypisania nowym zmiennym wartości będących kolejnymi elementami krotki. Można tego dokonać bez konieczności stosowania pętli, \n",
    "a zatem przechodzenia całej krotki element po elemencie. Dokonujemy tego poprzez składnię:\n",
    "`(nazwa_zmiennej1, nazwa_zmiennej2, ..., nazwa_zmiennejN) = nazwa_krotki_o_N_elementach`."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 122,
  "id": "c71ac783-c2bc-4fd8-b6a4-15560c17d9c5",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "kuchnia i łazienka\n"
    ]
    }
  ],
  "source": [
    "dom = (\"kuchnia\", \"łazienka\", \"sypialnia\", \"sypialnia\", \"jadalnia\", \"salon\")\n",
    "(pomieszczenie1, pomieszczenie2) = dom[:2]\n",
    "print(pomieszczenie1 + \" i \" + pomieszczenie2)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "4661aea5-b0e8-444d-a3c6-6c5d8147884c",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Mechanizm ten możemy wykorzystać do bardzo prostego w zapisie zamienienia wartości dla dwóch zmiennych. Mianowicie zamiast używać dodatkowej zmiennej pomocniczej, jak tutaj:"
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 9,
  "id": "24ae95ea-c8c1-474a-b1be-26582804279c",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "9 0\n"
    ]
    }
  ],
  "source": [
    "a = 0\n",
    "b = 9\n",
    "temp = a\n",
    "a = b\n",
    "b = temp\n",
    "print(a, b)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "7ed70dc2-ecd9-4ff8-a8d6-dc4e13830a0e",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "można bardzo prosto dokonać zamiany w następujący sposób."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 10,
  "id": "ddb258cc-198c-4b15-acaf-42a934cdbd73",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "9 0\n"
    ]
    }
  ],
  "source": [
    "a = 0\n",
    "b = 9\n",
    "(b, a) = (a, b)\n",
    "print(a,b)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "b2cd1803-55cc-48e0-8003-f458ccff7d75",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "W celu poruszania się po elementach w krotce stosujemy te same metody jak dla list. Zastosowanie mają tutaj również funkcje `len()`, zwracająca długość krotki, czyli liczbę jej elementów, oraz `range()`."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 11,
  "id": "2a4a64f8-2968-4af6-9da3-9b2b33211d0d",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "Liczba pomieszczeń to: 6\n"
    ]
    }
  ],
  "source": [
    "dom = (\"kuchnia\", \"łazienka\", \"sypialnia\", \"sypialnia\", \"jadalnia\", \"salon\")\n",
    "l = 0\n",
    "for pom in dom :\n",
    "    l += 1\n",
    "print(\"Liczba pomieszczeń to:\", l)"
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 12,
  "id": "cf75ee67-d91e-4959-aedc-9c1e5e9d637b",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "łazienka\n",
      "sypialnia\n",
      "salon\n"
    ]
    }
  ],
  "source": [
    "dom = (\"kuchnia\", \"łazienka\", \"sypialnia\", \"sypialnia\", \"jadalnia\", \"salon\")\n",
    "for i in range(1, len(dom), 2) :\n",
    "        print(dom[i])\n"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "f262dd37-6108-4693-86bf-c587d0f359dc",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "### Zbiory\n",
    "\n",
    "Zbiór jest kolejną strukturą danych, która pozwala na przechowywanie wielu wartości pod jedną zmienną. Zbiór jest nieuporządkowaną kolekcją wartości dowolnego typu, która nie zawiera powtórzeń. Zbiór ma ograniczoną modyfikowalność, tzn.\n",
    "można jedynie usuwać elementy ze zbioru oraz dodawać nowe. W celu zadeklarowania zbioru wypisujemy jego wartości w nawiasach klamrowych `{}`."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 13,
  "id": "032f778f-1b1c-4d6d-a270-4235bd2976a6",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'mleko', 'chleb', 'masło', 'woda'}\n"
    ]
    }
  ],
  "source": [
    "lista_zakupow = {\"masło\", \"chleb\", \"mleko\", \"woda\"}\n",
    "print(lista_zakupow)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "dcbc799a-7693-41fc-849d-07d4627fdb3b",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "**Uwaga:** Podkreślmy jeszcze raz, że zbiory nie są uporządkowane, a więc nie można odnosić się do jego poszczególnych elementów poprzez ich pozycję. W momencie wywołania `nazwa_zbioru[0]` otrzymamy błąd.\n",
    "\n",
    "W związku z powyższą uwagą poruszanie się po elementach zbioru jest ograniczone i możliwe jedynie przez pętlę `for`."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 14,
  "id": "959d6214-764a-4d62-952c-640768ff251a",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "mleko\n",
      "chleb\n",
      "masło\n",
      "woda\n"
    ]
    }
  ],
  "source": [
    "lista_zakupow = {\"masło\", \"chleb\", \"mleko\", \"woda\"}\n",
    "for produkt in lista_zakupow :\n",
    "    print(produkt)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "4f635ce7-303b-4731-b88e-afdcc712ceb1",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Jak już wspomnieliśmy wcześniej, modyfikowanie zawartości zbiorów ogranicza się jedynie do dodawania nowych elementów i usuwania już istniejących. W celu dodania pojedynczych elementów najprościej jest użyć metody `add()`. "
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 15,
  "id": "ef3c3a44-2ccc-498f-91be-313efe5d62fd",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'woda', 'mleko', 'chleb', 'ser', 'masło'}\n"
    ]
    }
  ],
  "source": [
    "lista_zakupow = {\"masło\", \"chleb\", \"mleko\", \"woda\"}\n",
    "lista_zakupow.add(\"masło\")        # nie otrzymamy błędu, ale element nie zostanie dodany\n",
    "lista_zakupow.add(\"ser\")\n",
    "print(lista_zakupow)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "df35ebc5-3344-421c-91b2-b60546723073",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Jeśli jednak chcemy dodać całą kolekcję elementów, to możemy użyć metody `update()`, której argumentem może być dowolna struktura przechowująca sekwencję wartości tzn. lista, krotka, zbiór, słownik."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 16,
  "id": "ccccc163-c334-40e7-b60a-1da692c2d983",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'woda', 'mleko', 'chleb', 'masło', 'ser'}\n",
      "{'woda', 'sałata', 'mleko', 'chleb', 'jabłko', 'masło', 'ser'}\n",
      "{'woda', 'pomidor', 'mleko', 'chleb', 'sałata', 'jabłko', 'ser', 'masło', 'cebula'}\n"
    ]
    }
  ],
  "source": [
    "lista_zakupow = {\"masło\", \"chleb\", \"mleko\", \"woda\"}\n",
    "lista_zakupow.update({\"ser\", \"masło\"})      # dodawanie całego zbioru\n",
    "print(lista_zakupow)\n",
    "lista_zakupow.update((\"jabłko\", \"sałata\"))  # dodawanie wszystkich elementów krotki\n",
    "print(lista_zakupow)\n",
    "lista = [\"woda\", \"woda\", \"pomidor\", \"cebula\"]\n",
    "lista_zakupow.update(lista)                # dodawanie wszystkich elementów listy\n",
    "print(lista_zakupow)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "a96af9f3-a5cc-46ea-bad9-b3aca6119bc6",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Usuwanie elementów możemy wykonać za pomocą metody `remove()` lub `discard()`. Główną różnicą między tymi metodami jest zgłaszanie błędu metody `remove()` w przypadku próby usunięcia elementu niewystępującego w zbiorze."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 17,
  "id": "c7dc2e11-2b37-4c41-88e0-814e5a1d4fa7",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'mleko', 'chleb', 'woda'}\n"
    ]
    }
  ],
  "source": [
    "lista_zakupow = {\"masło\", \"chleb\", \"mleko\", \"woda\"}\n",
    "lista_zakupow.remove(\"masło\")\n",
    "lista_zakupow.discard(\"masło\")            \n",
    "print(lista_zakupow)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "bbbaf8b8-b580-4ad1-b7db-8db23f367584",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Zwróćmy uwagę na jeszcze jeden problem związany z sumą dwóch zbiorów. Oczywiście, jeśli chcemy jedynie dopisać do jednego zbioru elementy z drugiego zbioru, to możemy użyć metody `update()`.\n",
    "Co jednak jeśli chcemy wynik takiej sumy przypisać nowemu zbiorowi. Wówczas poniższy kod nie spełni swojej roli ponieważ obydwa zbiory poniżej odwołują się do tego samego obiektu."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 18,
  "id": "e6282cac-f3ab-40ec-93ab-3c1c00255f7f",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'woda', 'pomidor', 'mleko', 'chleb', 'sałata', 'masło'}\n",
      "{'woda', 'pomidor', 'mleko', 'chleb', 'sałata', 'masło'}\n"
    ]
    }
  ],
  "source": [
    "lista_zakupow = {\"masło\", \"chleb\", \"mleko\", \"woda\"}\n",
    "lista_kopia = lista_zakupow\n",
    "lista_zakupow.update({\"masło\", \"pomidor\", \"sałata\"})\n",
    "print(lista_zakupow)\n",
    "print(lista_kopia)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "d1b2dfce-5bac-4035-80c5-fcde5d637494",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "W tym celu najlepiej jest użyć metody `union()`, która nie zmienia obiektu, który ją wywołał, a zwraca jedynie sumę zbioru wywołującego tę metodę oraz zbioru podanego jako argument (czyli de facto tworzy nowy obiekt)."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 19,
  "id": "29ac29b7-fc88-4034-a8d7-5372fd388401",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'mleko', 'chleb', 'masło', 'woda'}\n",
      "{'woda', 'pomidor', 'mleko', 'chleb', 'sałata', 'masło'}\n"
    ]
    }
  ],
  "source": [
    "lista_zakupow = {\"masło\", \"chleb\", \"mleko\", \"woda\"}\n",
    "lista_uzup = lista_zakupow.union({\"masło\", \"pomidor\", \"sałata\"})\n",
    "print(lista_zakupow)\n",
    "print(lista_uzup)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "b47499e1-e28c-4325-802b-10851b01292d",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "**Uwaga:** Podobnie jak poprzednio możemy przekonwertować zbiór na listę i wówczas mieć dostęp do większej liczby metod oraz móc modyfikować poszczególne elementy. Niestety ze względu na brak uporządkowania elementów w zbiorze nie mamy kontroli nad pozycjami jakie będą zajmowały poszczególne elementy zbioru po przekonwertowaniu."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 20,
  "id": "fcf5f9f5-be7e-40fc-bd05-99b7263f1522",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "['mleko', 'chleb', 'masło', 'woda']\n"
    ]
    }
  ],
  "source": [
    "lista_zakupow = {\"masło\", \"chleb\", \"mleko\", \"woda\"}\n",
    "print(list(lista_zakupow))"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "f7641292-a58d-4788-8a2c-4d8d311004e0",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "### Słowniki\n",
    "\n",
    "Słownik jest kolejną strukturą pozwalającą przechowywać kolekcję wartości. Jest on strukturą uporządkowaną (od wersji Python 3.7) oraz modyfikowalną. Nie pozwala jednak na duplikowanie się elementów. Główną różnicą między listą a słownikiem jest to, że w liście indeksy muszą być liczbami całkowitymi, a w słowniku indeksy mogą być (prawie) dowolnego typu.\n",
    "\n",
    "Można zatem myśleć o słowniku jako o odwzorowaniu pomiędzy zestawem indeksów (które są nazywane kluczami), a zestawem wartości. Każdemu kluczowi jest przyporządkowana dokładnie jedna wartość. Skojarzenie klucza i wartości nazywane jest parą klucz-wartość lub czasem elementem.\n",
    "\n",
    "Słownik definiujemy za pomocą nawiasów klamrowych, a jego elementy wypisujemy po przecinku. Ważną różnicą jest tutaj fakt, że każdy element ma składnię postaci `nazwa_klucza: wartość`."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 21,
  "id": "c9841552-2ae7-4369-bef7-88c22624ec7c",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'kuchnia': 10, 'łazienka': 5, 'salon': 35, 'jadalnia': 10, 'sypialnia': 11}\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "print(dom)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "0d921fee-9a4d-4776-bc7b-be222bd63894",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Jeśli znamy klucze danego słownika, to wartość przypisaną do klucza można uzyskać poprzez polecenie `nazwa_słownika[\"nazwa_klucza\"]` lub `nazwa_słownika.get(\"nazwa_klucza\")`."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 22,
  "id": "bff90e5b-d383-411d-8fa1-17c9bfeba2c5",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "35\n",
      "35\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "print(dom[\"salon\"])\n",
    "print(dom.get(\"salon\"))"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "44c7fd39-3b0f-488a-a6c6-d0e9342d2a68",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "W celu uzyskania listy kluczy lub listy wartości można użyć odpowiednio metod `keys()`, `values()`."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 23,
  "id": "28926924-7ca9-4957-a6a4-b1464bea835c",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "dict_keys(['kuchnia', 'łazienka', 'salon', 'jadalnia', 'sypialnia'])\n",
      "dict_values([10, 5, 35, 10, 11])\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "print(dom.keys())\n",
    "print(dom.values())"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "2000a8de-b926-4e3a-85d1-4706108efd1b",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Fakt, że słownik jest uporządkowany nie oznacza, że możemy w łatwy sposób odwoływać się do jego elementów po pozycji. Porządek w słowniku jest ustalony i niezmienny. Zatem możemy bezpiecznie konwertować słowniki. Popularną metodą jest metoda `items()`, która zwraca zawartość słownika w postaci listy, której elementami są krotki zawierające klucz na pierwszej pozycji i wartość na drugiej."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 24,
  "id": "29fdcce2-069d-4b4d-869e-23e6e2cf202f",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "dict_items([('kuchnia', 10), ('łazienka', 5), ('salon', 35), ('jadalnia', 10), ('sypialnia', 11)])\n",
      "('sypialnia', 11)\n",
      "[('kuchnia', 10), ('łazienka', 5), ('salon', 35)]\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "print(dom.items())            # jeśli chcemy uzyskać typ listy, to należy dopisać list(dom.items())\n",
    "print(list(dom.items())[-1])  # zatem tak możemy wyświetlić ostatni element\n",
    "print(list(dom.items())[:3])  # a tak 3 pierwsze elementy"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "8cc130f2-1f2e-42ba-9a7c-2592980b25bf",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Wartości przypisane kluczom możemy w łatwy sposób modyfikować (tak jak w przypadku list)."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 25,
  "id": "eca86ddb-4a2c-475f-81e8-8b8f2c2c79d0",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'kuchnia': 11, 'łazienka': 5, 'salon': 35, 'jadalnia': 10, 'sypialnia': 11}\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "dom[\"kuchnia\"] = 11\n",
    "print(dom)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "0ea4e9ef-ded4-4476-bb6f-02ff929f16cf",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Jeśli jednak chcemy zmienić nazwę klucza, to musimy usunąć dany element, a następnie dołączyć nowy ze zaktualizowaną nazwą klucza. \n",
    "\n",
    "Usuwanie elementów ze słownika wykonujemy podobnie jak usuwanie elementów z listy tzn. możemy użyć metody `pop()`, gdzie w miejsce argumentu wpisujemy nazwę klucza elementu do usunięci. Metoda ta zwraca usuwaną wartość przypisaną do klucza.  Możemy również użyć funkcji `del()` podobnie jak w przypadku list."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 26,
  "id": "da296140-a12e-4044-9199-0281d5e7045f",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "5\n",
      "{'kuchnia': 10, 'salon': 35, 'jadalnia': 10, 'sypialnia': 11}\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "print(dom.pop(\"łazienka\"))\n",
    "print(dom)"
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 27,
  "id": "74274f33-2327-464c-96ab-76538eb1a02a",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'kuchnia': 10, 'salon': 35, 'jadalnia': 10, 'sypialnia': 11}\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "del(dom[\"łazienka\"])\n",
    "print(dom)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "91d35c25-1e1a-4196-bbe2-f4ffc4b7c1c2",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Jeśli natomiast chcemy dodać nowy klucz wraz z wartością do słownika, wystarczy zwyczajnie użyć polecenia `nazwa_słownika[\"nazwa_klucza\"] = wartość`. Jeśli jednak użyjemy tego polecenia dla klucza, który już istnieje \n",
    "w słowniku, to jego wartość zostanie nadpisana przez wartość podaną w poleceniu."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 28,
  "id": "c1346f88-97f1-414c-b975-ade1b686d4c3",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'kuchnia': 11, 'łazienka': 5, 'salon': 35, 'jadalnia': 10, 'sypialnia': 11, 'garaż': 20}\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "dom[\"garaż\"] = 20\n",
    "dom[\"kuchnia\"] = 11\n",
    "print(dom)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "192089fa-c7a4-4408-bd8a-c16e7c0a88c0",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "W celu poruszania się po słowniku najlepiej jest wykorzystać pętlę `for` o składni `for klucz in nazwa_słownika:`, która pozwala przejść przez kolejne klucze danego słownika."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 29,
  "id": "60495d53-25b8-4bb0-9601-661171397854",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "kuchnia\n",
      "łazienka\n",
      "salon\n",
      "jadalnia\n",
      "sypialnia\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "for klucz in dom:\n",
    "    print(klucz)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "9e0a9a0a-4dbb-4a01-9a80-685e634b9bb5",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "W celu wyświetlenia wartości wystarczy użyć następujących instrukcji."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 30,
  "id": "287b6edf-94b9-4eca-b29b-b8f148a18685",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "10\n",
      "5\n",
      "35\n",
      "10\n",
      "11\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "for klucz in dom:\n",
    "    print(dom[klucz])"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "72b7b047-4b93-4f19-a218-5c0e53e7a724",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Ewentualnie możemy użyć też metody `values()`."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 31,
  "id": "e19c995d-0270-4738-ae8b-39db8acc70ec",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "10\n",
      "5\n",
      "35\n",
      "10\n",
      "11\n"
    ]
    }
  ],
  "source": [
    "for wartosc in dom.values():\n",
    "    print(wartosc)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "eab2c303-26e6-4230-90d2-14c7e18dd30e",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Możemy również wykorzystać metodę `items()` w celu użycia jednocześnie klucza i wartości jako zmiennej iterowanej."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 32,
  "id": "399de6f2-d067-496b-9ef2-72628d67f67f",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "kuchnia ma powierzchnię 10 m2\n",
      "łazienka ma powierzchnię 5 m2\n",
      "salon ma powierzchnię 35 m2\n",
      "jadalnia ma powierzchnię 10 m2\n",
      "sypialnia ma powierzchnię 11 m2\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "for (klucz, wartosc) in dom.items() :\n",
    "    print(klucz, \"ma powierzchnię\", wartosc, \"m2\")"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "884239c7-6ccd-4788-afb3-58cb9ba4c076",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "### Kilka ogólnych uwag dotyczących powyższych struktur\n",
    "\n",
    "Jak już widzieliśmy tworzenie kopii powyższych struktur może być mylące w działaniu, ponieważ zwykłe przypisanie tworzy jedynie alias do tego samego obiektu. Najprostszą metodą stworzenia prawdziwej kopii jest użycie metody `copy()`, która zwraca kopię listy, zbioru lub słownika. Nie ma powodów, aby tworzyć kopię krotki, ponieważ jest ona niemodyfikowalna. "
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 33,
  "id": "46ec924a-d198-4520-8b3f-a74e4470dafb",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "[4, 2, 3]\n",
      "[1, 2, 3]\n"
    ]
    }
  ],
  "source": [
    "lista = [1, 2, 3]\n",
    "nowa_lista = lista.copy()\n",
    "lista[0] = 4\n",
    "print(lista)        # zmienna lista uległa zmianie\n",
    "print(nowa_lista)    # zmienna nowa_lista się nie zmieniła"
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 34,
  "id": "1016c917-5cf7-4cc0-a355-43e0032fda85",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "{'kuchnia': 11, 'łazienka': 5, 'salon': 35, 'jadalnia': 10, 'sypialnia': 11}\n",
      "{'kuchnia': 10, 'łazienka': 5, 'salon': 35, 'jadalnia': 10, 'sypialnia': 11, 'garaż': 20}\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\": 35, \"jadalnia\": 10, \"sypialnia\": 11}\n",
    "nowy_dom = dom.copy()\n",
    "dom[\"kuchnia\"] = 11\n",
    "nowy_dom[\"garaż\"] = 20  # dodanie nowego klucza do słownika nowy_dom\n",
    "print(dom)\n",
    "print(nowy_dom)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "05defeb9-669b-4148-a78a-48b64321ac53",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "Warto również zauważyć, że istnieje łatwy sposób sprawdzania, czy dany element należy do listy, zbioru, krotki lub słownika. W tym celu wystarczy użyć instrukcji: `nazwa_elementu in nazwa_struktury`. Instrukcja ta zwraca `True`, o ile dany element należy do wymienionej struktury."
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 35,
  "id": "f0ff64b7-305e-4020-a4ff-da42ad6db600",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "True\n",
      "False\n",
      "================\n",
      "Masło już jest na liście zakupów!\n",
      "================\n"
    ]
    }
  ],
  "source": [
    "dom = {\"kuchnia\": 10, \"łazienka\": 5, \"salon\" : 35, \"jadalnia\" : 10, \"sypialnia\" : 11}\n",
    "lista_zakupow = {\"masło\", \"chleb\", \"mleko\", \"woda\"}\n",
    "roznosci = [\"słowo\", True, 3.14, 2+3, \"a\"*5, [1,2,3]]\n",
    "\n",
    "print(\"kuchnia\" in dom)\n",
    "print(10 in dom)\n",
    "\n",
    "print(\"================\")\n",
    "\n",
    "if \"masło\" in lista_zakupow:\n",
    "    print(\"Masło już jest na liście zakupów!\")\n",
    "\n",
    "print(\"================\")    \n",
    "    "
  ]
  },
  {
  "cell_type": "code",
  "execution_count": 36,
  "id": "4c0f4968-a8b7-46b4-91d3-52b4999ef206",
  "metadata": {
    "collapsed": false
  },
  "outputs": [
    {
    "name": "stdout",
    "output_type": "stream",
    "text": [
      "słowo\n",
      "True\n",
      "3.14\n",
      "5\n",
      "aaaaa\n",
      "[1, 2, 3]\n",
      "[]\n"
    ]
    }
  ],
  "source": [
    "while [1, 2, 3] in roznosci :\n",
    "    print(roznosci.pop(0))\n",
    "\n",
    "print(roznosci)"
  ]
  },
  {
  "cell_type": "markdown",
  "id": "02df596f",
  "metadata": {
    "collapsed": false
  },
  "source": [
    "**Zadanie 3.** Napisz program, który korzystając ze słownika wypisuje wszystkie cyfry danej liczby wraz z jej ilością wystąpień w tej liczbie."
  ]
  },
  {
  "cell_type": "markdown",
  "id": "7278034f",
  "metadata": {
    "collapsed": false
  },
  "source": [
  ]
  },
  {
  "cell_type": "markdown",
  "id": "95826b7b",
  "metadata": {
    "collapsed": false
  },
  "source": [
  ]
  },
  {
  "cell_type": "markdown",
  "id": "d257f79e",
  "metadata": {
    "collapsed": false
  },
  "source": [
  ]
  }
],
"metadata": {
  "kernelspec": {
  "argv": [
    "/usr/bin/python3",
    "-m",
    "ipykernel",
    "--HistoryManager.enabled=False",
    "--matplotlib=inline",
    "-c",
    "%config InlineBackend.figure_formats = set(['retina'])\nimport matplotlib; matplotlib.rcParams['figure.figsize'] = (12, 7)",
    "-f",
    "{connection_file}"
  ],
  "display_name": "Python 3 (system-wide)",
  "env": {
  },
  "language": "python",
  "metadata": {
    "cocalc": {
    "description": "Python 3 programming language",
    "priority": 100,
    "url": "https://www.python.org/"
    }
  },
  "name": "python3",
  "resource_dir": "/ext/jupyter/kernels/python3"
  },
  "language_info": {
  "codemirror_mode": {
    "name": "ipython",
    "version": 3
  },
  "file_extension": ".py",
  "mimetype": "text/x-python",
  "name": "python",
  "nbconvert_exporter": "python",
  "pygments_lexer": "ipython3",
  "version": "3.10.12"
  }
},
"nbformat": 4,
"nbformat_minor": 4
}
uwaga: portal używa ciasteczek tylko do obsługi tzw. sesji...