├── Lecture_1.ipynb ├── Lecture_10.ipynb ├── Lecture_11.ipynb ├── Lecture_13.ipynb ├── Lecture_14.ipynb ├── Lecture_2.ipynb ├── Lecture_3.ipynb ├── Lecture_4.ipynb ├── Lecture_5.ipynb ├── Lecture_6.ipynb ├── Lecture_7_8.ipynb ├── Lecture_9.ipynb └── README.md /Lecture_1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "collapsed_sections": [ 8 | "KbL-8UO6_gg3", 9 | "Mu5OOb_R_iSO", 10 | "qHZbQUmCC-N1", 11 | "1Pudv049E5zL", 12 | "Ws7jmlf_Fyh7", 13 | "GPdgxoPCIaG5", 14 | "wIQuzy4mZQGS", 15 | "zl8zLUoIgf0b", 16 | "LKo9G3grfr4n", 17 | "KWlJocc0gj8T", 18 | "qarkDDHT5dM2", 19 | "O7OiFziPgydH", 20 | "lTPVCHAFSmBr", 21 | "omYnbJiPUZmL" 22 | ] 23 | }, 24 | "kernelspec": { 25 | "name": "python3", 26 | "display_name": "Python 3" 27 | }, 28 | "language_info": { 29 | "name": "python" 30 | } 31 | }, 32 | "cells": [ 33 | { 34 | "cell_type": "markdown", 35 | "source": [ 36 | "# Python-1, Лекция 1\n", 37 | "\n", 38 | "Лектор: Петров Тимур" 39 | ], 40 | "metadata": { 41 | "id": "xbKgms5k_a6H" 42 | } 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "source": [ 47 | "## Пара вводных слов" 48 | ], 49 | "metadata": { 50 | "id": "KbL-8UO6_gg3" 51 | } 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "source": [ 56 | "### Что вообще такое Python?" 57 | ], 58 | "metadata": { 59 | "id": "Mu5OOb_R_iSO" 60 | } 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "source": [ 65 | "Если вы попробуете поискать запрос жанра \"Топ-10 самых популярных языков программирования\", то вы неизбежно наткнетесь на Python ([Пруф 1](https://habr.com/ru/articles/730954/), [Пруф 2](https://www.tiobe.com/tiobe-index/)). А если говорить про, например, Data Science, то этот язык будет топ-1 и далеко впереди. В чем же секрет и что это такое?\n", 66 | "\n", 67 | "Python - это ЯП, который можно использовать почти для всего угодно (поэтому он называется языкос \"общего назначения\"): исследовать данные, сделать веб-страничку, обучить ML модель и так далее. Имея в багаже Python вы можете сделать практически что угодно (если не углубляться в детали, конечно же)\n", 68 | "\n", 69 | "Главный плюс Python - это его простота и читабельность (на самом деле это одна из первых причин, почему вообще этот язык создавали, это можно увидеть в самом Дзене Python):" 70 | ], 71 | "metadata": { 72 | "id": "qdBO7y6l_lDW" 73 | } 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": { 79 | "colab": { 80 | "base_uri": "https://localhost:8080/" 81 | }, 82 | "id": "Yy7LQTdz_X1l", 83 | "outputId": "9decf02a-a6d6-4ea9-a56a-4c1b9abae28c" 84 | }, 85 | "outputs": [ 86 | { 87 | "output_type": "stream", 88 | "name": "stdout", 89 | "text": [ 90 | "The Zen of Python, by Tim Peters\n", 91 | "\n", 92 | "Beautiful is better than ugly.\n", 93 | "Explicit is better than implicit.\n", 94 | "Simple is better than complex.\n", 95 | "Complex is better than complicated.\n", 96 | "Flat is better than nested.\n", 97 | "Sparse is better than dense.\n", 98 | "Readability counts.\n", 99 | "Special cases aren't special enough to break the rules.\n", 100 | "Although practicality beats purity.\n", 101 | "Errors should never pass silently.\n", 102 | "Unless explicitly silenced.\n", 103 | "In the face of ambiguity, refuse the temptation to guess.\n", 104 | "There should be one-- and preferably only one --obvious way to do it.\n", 105 | "Although that way may not be obvious at first unless you're Dutch.\n", 106 | "Now is better than never.\n", 107 | "Although never is often better than *right* now.\n", 108 | "If the implementation is hard to explain, it's a bad idea.\n", 109 | "If the implementation is easy to explain, it may be a good idea.\n", 110 | "Namespaces are one honking great idea -- let's do more of those!\n" 111 | ] 112 | } 113 | ], 114 | "source": [ 115 | "import this" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "source": [ 121 | "Мы же, естественно, должны преисполниться этим Дзеном и быть в тренде)\n", 122 | "\n", 123 | "А как вообще писать? На это есть [ответ](https://peps.python.org/pep-0008/)\n" 124 | ], 125 | "metadata": { 126 | "id": "4lySffD3Ck7R" 127 | } 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "source": [ 132 | "### Пара организационных моментов про курс" 133 | ], 134 | "metadata": { 135 | "id": "qHZbQUmCC-N1" 136 | } 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "source": [ 141 | "$$О_{итог} = 0,3 * О_{экз} + 0,7 * О_{накоп}$$\n", 142 | "\n", 143 | "$$О_{накоп} = 0,3 * О_{сем} + 0,7 * О_{дз}$$\n", 144 | "\n", 145 | "Если развернуть, то будет:\n", 146 | "\n", 147 | "$$О_{итог} = 0,3 * О_{экз} + 0,21 * О_{сем} + 0,49 * О_{дз}$$\n", 148 | "\n", 149 | "Поэтому все важно и нужно. Автомат ставится при условиях:\n", 150 | "\n", 151 | "$$\\begin{cases} О_{накоп} \\geq 8 \\\\ О_{сем} \\geq 8 \\end{cases}$$\n", 152 | "\n", 153 | "Округление оценки - округляется **только** итог. Округление арифметическое, блокирующих оценок нет.\n", 154 | "\n", 155 | "Домашние задания = контест после каждой пары. Каждый контест имеет 2 дедлайна: мягкий и жесткий. Первая неделя - мягкий дедлайн (все задачи имеют полный балл), вторая неделя - жесткий дедлайн (имеют весь 0.7). После жесткого дедлайна задачи не оцениваются\n", 156 | "\n", 157 | "Правила оценивания семинаров выбираются самими семинаристами и проставляются ими же\n", 158 | "\n", 159 | "А теперь к делу!" 160 | ], 161 | "metadata": { 162 | "id": "fVbqAjOWDEDQ" 163 | } 164 | }, 165 | { 166 | "cell_type": "markdown", 167 | "source": [ 168 | "## Ввод-вывод данных" 169 | ], 170 | "metadata": { 171 | "id": "1Pudv049E5zL" 172 | } 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "source": [ 177 | "Первый вопрос, который встает в любом ЯП - как вводить и выводить данные?\n", 178 | "\n", 179 | "Есть традиционно 2 способа ввести данные:\n", 180 | "\n", 181 | "* Ввести ручками самостоятельно\n", 182 | "\n", 183 | "* Подать какой-нибудь файл, в котором лежат эти данные\n", 184 | "\n", 185 | "Есть традиционно 2 способа вывести данные:\n", 186 | "\n", 187 | "* В консоли (ручной вывод)\n", 188 | "\n", 189 | "* В файл (куда-нибудь что-нибудь записать и получить файл на выходе)\n", 190 | "\n", 191 | "Давайте разбираться:\n" 192 | ], 193 | "metadata": { 194 | "id": "GFGMfqhvFAPA" 195 | } 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "source": [ 200 | "#### Ручной ввод-вывод данных" 201 | ], 202 | "metadata": { 203 | "id": "Ws7jmlf_Fyh7" 204 | } 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "source": [ 209 | "Ручной ввод и вывод данных осуществляется с помощью функций **input()** и **print()**:" 210 | ], 211 | "metadata": { 212 | "id": "GRhBaoHHF1a4" 213 | } 214 | }, 215 | { 216 | "cell_type": "code", 217 | "source": [ 218 | "a = input()\n", 219 | "print(a)" 220 | ], 221 | "metadata": { 222 | "colab": { 223 | "base_uri": "https://localhost:8080/" 224 | }, 225 | "id": "7r1k6wp-F1sf", 226 | "outputId": "1471159a-1621-4e38-a0ba-62d92c8ae101" 227 | }, 228 | "execution_count": null, 229 | "outputs": [ 230 | { 231 | "output_type": "stream", 232 | "name": "stdout", 233 | "text": [ 234 | "dasdas\n", 235 | "dasdas\n" 236 | ] 237 | } 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "source": [ 243 | "Давайте поймем, что происходит при вызове данных функций:\n", 244 | "\n", 245 | "* input() - берется вся строка, считывается и записывается как есть\n", 246 | "\n", 247 | "* print() - печатает все, что находится в переменной\n", 248 | "\n", 249 | "А что это за скобочки? По существу это **аргументы** функции. Про аргументы мы поговорим позже, когда будем обсуждать функции в Python, а пока что, для нашего понимания:\n", 250 | "\n", 251 | "* input(text) - выдает перед вводом text (зачем надо - чтобы сказать пользователю, а что ему вводить)\n", 252 | "\n", 253 | "* print(smth) - выведи то, что я указал" 254 | ], 255 | "metadata": { 256 | "id": "vjHZMjR5GEHi" 257 | } 258 | }, 259 | { 260 | "cell_type": "code", 261 | "source": [ 262 | "a = input(\"Insert your age, please: \")\n", 263 | "print(a)" 264 | ], 265 | "metadata": { 266 | "colab": { 267 | "base_uri": "https://localhost:8080/" 268 | }, 269 | "id": "gXg1SzSEHWHt", 270 | "outputId": "6ff2c0ef-6426-424d-def3-cde2739e8367" 271 | }, 272 | "execution_count": null, 273 | "outputs": [ 274 | { 275 | "output_type": "stream", 276 | "name": "stdout", 277 | "text": [ 278 | "Insert your age, please: 25\n", 279 | "25\n" 280 | ] 281 | } 282 | ] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "source": [ 287 | "А допустим, что я хочу ввести сразу не 1 значение, а сразу 2, что же тогда делать?" 288 | ], 289 | "metadata": { 290 | "id": "QUpgO_PQIBYl" 291 | } 292 | }, 293 | { 294 | "cell_type": "code", 295 | "source": [ 296 | "a, b = input()\n", 297 | "print(a, b)" 298 | ], 299 | "metadata": { 300 | "colab": { 301 | "base_uri": "https://localhost:8080/", 302 | "height": 222 303 | }, 304 | "id": "0Z-HgEVLIHB0", 305 | "outputId": "075de5b5-0327-4f58-ae54-e598ee2c6941" 306 | }, 307 | "execution_count": null, 308 | "outputs": [ 309 | { 310 | "name": "stdout", 311 | "output_type": "stream", 312 | "text": [ 313 | "a a\n" 314 | ] 315 | }, 316 | { 317 | "output_type": "error", 318 | "ename": "ValueError", 319 | "evalue": "ignored", 320 | "traceback": [ 321 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 322 | "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", 323 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 324 | "\u001b[0;31mValueError\u001b[0m: too many values to unpack (expected 2)" 325 | ] 326 | } 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "source": [ 332 | "Просто попросить ввести два значения не получится, к сожалению. Но эту оказию мы обойдем через некоторое время\n", 333 | "\n", 334 | "Recap:\n", 335 | "\n", 336 | "* input() - вводим данные как есть\n", 337 | "\n", 338 | "* print() - печатаем переданные данные" 339 | ], 340 | "metadata": { 341 | "id": "on4ZTMZUILKI" 342 | } 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "source": [ 347 | "#### Ввод-вывод из файлов" 348 | ], 349 | "metadata": { 350 | "id": "GPdgxoPCIaG5" 351 | } 352 | }, 353 | { 354 | "cell_type": "markdown", 355 | "source": [ 356 | "С вводом из файла все гораздо сложнее. Задача: как положить слона в холодильник?" 357 | ], 358 | "metadata": { 359 | "id": "tfu_wbvHId3C" 360 | } 361 | }, 362 | { 363 | "cell_type": "markdown", 364 | "source": [ 365 | "**Ответ:**\n", 366 | "\n", 367 | "1. Открываем холодильник\n", 368 | "\n", 369 | "2. Кладем слона\n", 370 | "\n", 371 | "3. Закрываем холодильник" 372 | ], 373 | "metadata": { 374 | "id": "oKNKF1SKI1Cu" 375 | } 376 | }, 377 | { 378 | "cell_type": "markdown", 379 | "source": [ 380 | "К чему бы это все? Как считать данные с файла?\n", 381 | "\n", 382 | "1. Открыть файл\n", 383 | "\n", 384 | "2. Считать данные\n", 385 | "\n", 386 | "3. Закрыть файл\n", 387 | "\n", 388 | "Логика абсолютно такая же!" 389 | ], 390 | "metadata": { 391 | "id": "lb8PpfpLJBfT" 392 | } 393 | }, 394 | { 395 | "cell_type": "markdown", 396 | "source": [ 397 | "Шаг 1. Открываем файл\n", 398 | "\n", 399 | "В этом нам поможет функция open(file, mode, encoding) (на самом деле здесь есть еще несколько переменных, но мы остановимся пока тольк она этих)\n", 400 | "\n", 401 | "Что здесь есть?\n", 402 | "\n", 403 | "* file - путь до файла (что брать)\n", 404 | "\n", 405 | "* mode - что мы хотим с ним делать (есть 4 важных буквы: r (read), w (write), x (exclusive), a (add))\n", 406 | "\n", 407 | "* encoding - кодировка (почему это важно - очень часто файлы с русскими буквами могут считываться как какая-то фигня. В данном случае, скорее всего, там кодировка не utf-8, как обычно, а cp-1252, привет, Винда)" 408 | ], 409 | "metadata": { 410 | "id": "_Q4j-hTkJOFd" 411 | } 412 | }, 413 | { 414 | "cell_type": "code", 415 | "source": [ 416 | "f = open(\"file.txt\", 'r') # открываем файл file.txt, хотим его читать\n", 417 | "f" 418 | ], 419 | "metadata": { 420 | "colab": { 421 | "base_uri": "https://localhost:8080/" 422 | }, 423 | "id": "XIoaBaKCWCXG", 424 | "outputId": "33b78728-3a83-4f3e-8afb-ddd8061cb49e" 425 | }, 426 | "execution_count": null, 427 | "outputs": [ 428 | { 429 | "output_type": "execute_result", 430 | "data": { 431 | "text/plain": [ 432 | "<_io.TextIOWrapper name='file.txt' mode='r' encoding='UTF-8'>" 433 | ] 434 | }, 435 | "metadata": {}, 436 | "execution_count": 7 437 | } 438 | ] 439 | }, 440 | { 441 | "cell_type": "markdown", 442 | "source": [ 443 | "Что мы получили по итогу? Если очень просто, то мы установили **файловый поток** (по сути это некоторая связь между нашей программой и файлом), с помощью которого мы можем обращаться к тому, что находится внутри файла.\n", 444 | "\n", 445 | "Представьте себе, что мы будто в Гугл Доке, в котором мы поставили курсор, с помощью которого будем считывать. Мы можем двигать курсор, что-то считывать, что-то записывать (если открываем на чтение/добавление)\n", 446 | "\n", 447 | "Но про это более подробно мы поговорим в следующий раз)" 448 | ], 449 | "metadata": { 450 | "id": "esZ2V7eAWWys" 451 | } 452 | }, 453 | { 454 | "cell_type": "markdown", 455 | "source": [ 456 | "Шаг 2. Считываем данные\n", 457 | "\n", 458 | "Сейчас мы рассмотрим 3 самых простых метода для чтения, про более изощренные вещи мы поговорим на следующей паре. Что умеем?\n", 459 | "\n", 460 | "* readline() - прочти линию (до перевода строки)\n", 461 | "\n", 462 | "* readlines() - прочти все линии\n", 463 | "\n", 464 | "* read(size) - прочитай ровно size элементов (если не указывать, то прочтем все, что есть)\n", 465 | "\n", 466 | "В чем разница между read() и readlines()? А вот в чем:" 467 | ], 468 | "metadata": { 469 | "id": "pSoq3aTvW74x" 470 | } 471 | }, 472 | { 473 | "cell_type": "code", 474 | "source": [ 475 | "a = f.read()\n", 476 | "print(a)\n", 477 | "f.close()\n", 478 | "f = open(\"file.txt\", 'r')\n", 479 | "b = f.readlines()\n", 480 | "print(b)\n", 481 | "f.close()" 482 | ], 483 | "metadata": { 484 | "colab": { 485 | "base_uri": "https://localhost:8080/" 486 | }, 487 | "id": "F8RMaE9OWME5", 488 | "outputId": "8dc7ef4f-9aba-4b7c-df72-14c77a1d7181" 489 | }, 490 | "execution_count": null, 491 | "outputs": [ 492 | { 493 | "output_type": "stream", 494 | "name": "stdout", 495 | "text": [ 496 | "hello World\n", 497 | "Python is cool\n", 498 | "a b c\n", 499 | "['hello World\\n', 'Python is cool\\n', 'a b c']\n" 500 | ] 501 | } 502 | ] 503 | }, 504 | { 505 | "cell_type": "code", 506 | "source": [ 507 | "f = open(\"file.txt\", 'r')\n", 508 | "c = f.readline()\n", 509 | "print(c)\n", 510 | "d = f.readline()\n", 511 | "print(d)" 512 | ], 513 | "metadata": { 514 | "colab": { 515 | "base_uri": "https://localhost:8080/" 516 | }, 517 | "id": "eiIivagDZGBT", 518 | "outputId": "d5485c09-2642-4a3d-c8a9-9796887d3af2" 519 | }, 520 | "execution_count": null, 521 | "outputs": [ 522 | { 523 | "output_type": "stream", 524 | "name": "stdout", 525 | "text": [ 526 | "hello World\n", 527 | "\n", 528 | "Python is cool\n", 529 | "\n" 530 | ] 531 | } 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "source": [ 537 | "f.close()" 538 | ], 539 | "metadata": { 540 | "id": "p8IC0M4WZMLX" 541 | }, 542 | "execution_count": null, 543 | "outputs": [] 544 | }, 545 | { 546 | "cell_type": "markdown", 547 | "source": [ 548 | "Шаг 3. Закрываем файл\n", 549 | "\n", 550 | "Помните, что мы установили поток (или связь) между программой и файлом. Это жрет ресурсы (потому что это надо хранить и поддерживать). Поэтому в тот момент, когда мы закончили работать с файлом (считали или записали все, что нам надо), необходимо связь **закрыть** (иначе будет протекать, представьте себе, что будет, если оставить холодильник открытым)\n", 551 | "\n", 552 | "По логике вещей, если открываем с помощью функции open(), то закрываем с помощью метода close(), здесь все просто, ничего другого передавать не надо" 553 | ], 554 | "metadata": { 555 | "id": "1GPuf3u9W_Zx" 556 | } 557 | }, 558 | { 559 | "cell_type": "code", 560 | "source": [ 561 | "f.close() #закрыли, живем и радуемся" 562 | ], 563 | "metadata": { 564 | "id": "-Q4WOOdlXsdU" 565 | }, 566 | "execution_count": null, 567 | "outputs": [] 568 | }, 569 | { 570 | "cell_type": "markdown", 571 | "source": [ 572 | "Recap:\n", 573 | "\n", 574 | "* open() - считать\n", 575 | "\n", 576 | "* read(), readline(), readlines() - считать данные\n", 577 | "\n", 578 | "* close() - закрыть" 579 | ], 580 | "metadata": { 581 | "id": "nuBtUmjuXyaC" 582 | } 583 | }, 584 | { 585 | "cell_type": "markdown", 586 | "source": [ 587 | "## Типы данных" 588 | ], 589 | "metadata": { 590 | "id": "wIQuzy4mZQGS" 591 | } 592 | }, 593 | { 594 | "cell_type": "markdown", 595 | "source": [ 596 | "Ну супер, мы умеем что-то считывать и умеем что-то выводить. Но как будто что-то теряется...\n", 597 | "\n", 598 | "А обрабатывать как? А что вообще делать? Мы получили какие-то строчки и на этом все. Теперь стоит поговорить про типы данных, которые у нас есть и как они друг с другом работают\n", 599 | "\n", 600 | "Если вы учили, например, C++ или Pascal ранее, то могли увидеть большую разницу между тем, как здесь происходит инициализация переменных и как она происходит там: **мы не указываем тип переменной**\n", 601 | "\n", 602 | "А почему? А потому что Python - это язык с *динамической типизацией* (соответственно, C++ имеет *статическую типизацию*). Что это значит? Это значит, что тип данных определяется во время присваивания значения. Поэтому возможно сделать вот так:" 603 | ], 604 | "metadata": { 605 | "id": "bWn-pBAaZWFh" 606 | } 607 | }, 608 | { 609 | "cell_type": "code", 610 | "source": [ 611 | "a = 5 # здесь лежит число\n", 612 | "print(a)\n", 613 | "a = 'hello' # здесь лежит строка\n", 614 | "print(a)" 615 | ], 616 | "metadata": { 617 | "colab": { 618 | "base_uri": "https://localhost:8080/" 619 | }, 620 | "id": "GwQW_FnKaNqu", 621 | "outputId": "5ed4a88c-c767-4022-de22-efac7c4cd395" 622 | }, 623 | "execution_count": null, 624 | "outputs": [ 625 | { 626 | "output_type": "stream", 627 | "name": "stdout", 628 | "text": [ 629 | "5\n", 630 | "hello\n" 631 | ] 632 | } 633 | ] 634 | }, 635 | { 636 | "cell_type": "markdown", 637 | "source": [ 638 | "Ну хорошо, он там чет наколдовал, а как мне понять, какой тип лежит? Очень просто - есть функция type()!" 639 | ], 640 | "metadata": { 641 | "id": "qSYuE2CtbXNx" 642 | } 643 | }, 644 | { 645 | "cell_type": "code", 646 | "source": [ 647 | "a = 5 # здесь лежит число\n", 648 | "print(a, type(a))\n", 649 | "a = 'hello' # здесь лежит строка\n", 650 | "print(a, type(a))" 651 | ], 652 | "metadata": { 653 | "colab": { 654 | "base_uri": "https://localhost:8080/" 655 | }, 656 | "id": "nBuc9jK_bfZ4", 657 | "outputId": "58504d1c-6925-4a60-dc60-1f2f5798f3a5" 658 | }, 659 | "execution_count": null, 660 | "outputs": [ 661 | { 662 | "output_type": "stream", 663 | "name": "stdout", 664 | "text": [ 665 | "5 \n", 666 | "hello \n" 667 | ] 668 | } 669 | ] 670 | }, 671 | { 672 | "cell_type": "markdown", 673 | "source": [ 674 | "Вуаля, в одном месте число, в другом строка.\n", 675 | "\n", 676 | "Какие типы данных есть в Python и что с ними можно делать?" 677 | ], 678 | "metadata": { 679 | "id": "ILeN8ZAObigU" 680 | } 681 | }, 682 | { 683 | "cell_type": "markdown", 684 | "source": [ 685 | "#### Логическая переменная (Bool)" 686 | ], 687 | "metadata": { 688 | "id": "Kv9m13i-gtNO" 689 | } 690 | }, 691 | { 692 | "cell_type": "markdown", 693 | "source": [ 694 | "Самый простой тип, который принимает значения True и False. С точки зрения чисел 0 - это False, все остальное - это True (про приведение типов чуть позже поговорим)" 695 | ], 696 | "metadata": { 697 | "id": "PoLKtSfo7G_6" 698 | } 699 | }, 700 | { 701 | "cell_type": "code", 702 | "source": [ 703 | "a = True\n", 704 | "print(a)\n", 705 | "a = False\n", 706 | "print(a)" 707 | ], 708 | "metadata": { 709 | "colab": { 710 | "base_uri": "https://localhost:8080/" 711 | }, 712 | "id": "Z_AB6IO07MIm", 713 | "outputId": "eb88f9ce-d738-4b34-f7c3-b292a66f6822" 714 | }, 715 | "execution_count": null, 716 | "outputs": [ 717 | { 718 | "output_type": "stream", 719 | "name": "stdout", 720 | "text": [ 721 | "True\n", 722 | "False\n" 723 | ] 724 | } 725 | ] 726 | }, 727 | { 728 | "cell_type": "markdown", 729 | "source": [ 730 | "#### Int, Float" 731 | ], 732 | "metadata": { 733 | "id": "oVX882ERbpBA" 734 | } 735 | }, 736 | { 737 | "cell_type": "markdown", 738 | "source": [ 739 | "Числа (целое или с плавающей точкой). В чем разница? В том, как хранится (можно посмотреть [вот тут](https://ru.wikipedia.org/wiki/Число_с_плавающей_запятой)). Давайте разбираться по частям:" 740 | ], 741 | "metadata": { 742 | "id": "AZTyrBVPbzN3" 743 | } 744 | }, 745 | { 746 | "cell_type": "code", 747 | "source": [ 748 | "a = 5\n", 749 | "b = 1.12\n", 750 | "print(type(a), type(b))" 751 | ], 752 | "metadata": { 753 | "colab": { 754 | "base_uri": "https://localhost:8080/" 755 | }, 756 | "id": "Yx9QhmxMbw3h", 757 | "outputId": "0c5c1257-937f-457d-a193-abaa9a50133d" 758 | }, 759 | "execution_count": null, 760 | "outputs": [ 761 | { 762 | "output_type": "stream", 763 | "name": "stdout", 764 | "text": [ 765 | " \n" 766 | ] 767 | } 768 | ] 769 | }, 770 | { 771 | "cell_type": "markdown", 772 | "source": [ 773 | "Что можно делать с целым числом? Арифметические вычисления и взятие модуля!" 774 | ], 775 | "metadata": { 776 | "id": "QKR4NNuZcQFg" 777 | } 778 | }, 779 | { 780 | "cell_type": "code", 781 | "source": [ 782 | "a = 5\n", 783 | "b = 10\n", 784 | "\n", 785 | "print(a + b) #сложение\n", 786 | "print(a - b) #вычитание\n", 787 | "print(a * b) #умножение\n", 788 | "print(abs(-a))" 789 | ], 790 | "metadata": { 791 | "colab": { 792 | "base_uri": "https://localhost:8080/" 793 | }, 794 | "id": "bNZ3Lx0qcXhp", 795 | "outputId": "5de1378f-20e5-4cef-b1c6-43d9345575ef" 796 | }, 797 | "execution_count": null, 798 | "outputs": [ 799 | { 800 | "output_type": "stream", 801 | "name": "stdout", 802 | "text": [ 803 | "15\n", 804 | "-5\n", 805 | "50\n", 806 | "5\n" 807 | ] 808 | } 809 | ] 810 | }, 811 | { 812 | "cell_type": "markdown", 813 | "source": [ 814 | "Особо надо посмотреть на деление:" 815 | ], 816 | "metadata": { 817 | "id": "eMEq2HjWch4X" 818 | } 819 | }, 820 | { 821 | "cell_type": "code", 822 | "source": [ 823 | "print(b / a, type(b / a)) # реальное деление (получается float)\n", 824 | "print(b // a, type(b // a)) # целочисленное деление (получается int)\n", 825 | "print(a % b, type(a % b)) # остаток от деления (получается int)" 826 | ], 827 | "metadata": { 828 | "colab": { 829 | "base_uri": "https://localhost:8080/" 830 | }, 831 | "id": "gpmKrRuVcmjd", 832 | "outputId": "a60084c8-2561-4ce2-fbcd-3853d3d81a8b" 833 | }, 834 | "execution_count": null, 835 | "outputs": [ 836 | { 837 | "output_type": "stream", 838 | "name": "stdout", 839 | "text": [ 840 | "2.0 \n", 841 | "2 \n", 842 | "5 \n" 843 | ] 844 | } 845 | ] 846 | }, 847 | { 848 | "cell_type": "markdown", 849 | "source": [ 850 | "Можно ли делать целочисленное деление на float? Шок, но можно!" 851 | ], 852 | "metadata": { 853 | "id": "cvDbD2lydAil" 854 | } 855 | }, 856 | { 857 | "cell_type": "code", 858 | "source": [ 859 | "a = 5\n", 860 | "b = 1.12\n", 861 | "print(a // b)\n", 862 | "print(a % b)" 863 | ], 864 | "metadata": { 865 | "colab": { 866 | "base_uri": "https://localhost:8080/" 867 | }, 868 | "id": "F6Hsr8DNdFvq", 869 | "outputId": "fb316738-2ec3-4652-84e8-e9a637c7805c" 870 | }, 871 | "execution_count": null, 872 | "outputs": [ 873 | { 874 | "output_type": "stream", 875 | "name": "stdout", 876 | "text": [ 877 | "4.0\n", 878 | "0.5199999999999996\n" 879 | ] 880 | } 881 | ] 882 | }, 883 | { 884 | "cell_type": "markdown", 885 | "source": [ 886 | "Как понимать остаток при делении и целочисленное деление? (Это поможет на курсе дискретной математики)\n", 887 | "\n", 888 | "Смотрите, вспоминаем школьную программу. Можно делить как есть (условно, 7 / 3 = 2,(3)). А моооожно делить с остатком:\n", 889 | "\n", 890 | "$$7 / 3 = 2 \\text{ (остаток 1)} $$\n", 891 | "\n", 892 | "И по существу будет, что:" 893 | ], 894 | "metadata": { 895 | "id": "sbyylRr8dZYk" 896 | } 897 | }, 898 | { 899 | "cell_type": "code", 900 | "source": [ 901 | "print(7 // 3, 7 % 3) ##о, ура, прям как в формуле" 902 | ], 903 | "metadata": { 904 | "colab": { 905 | "base_uri": "https://localhost:8080/" 906 | }, 907 | "id": "icw_pIlld9P6", 908 | "outputId": "eb529cc0-8d4a-4f73-f41e-215a064dffd9" 909 | }, 910 | "execution_count": null, 911 | "outputs": [ 912 | { 913 | "output_type": "stream", 914 | "name": "stdout", 915 | "text": [ 916 | "2 1\n" 917 | ] 918 | } 919 | ] 920 | }, 921 | { 922 | "cell_type": "markdown", 923 | "source": [ 924 | "Если пока сложновато воспринимать, то попробуйте дома посчитать результаты следующих делений с остатком:\n", 925 | "\n", 926 | "1. $15 / 5$\n", 927 | "\n", 928 | "2. $15 / 6$\n", 929 | "\n", 930 | "3. $-15 / 6$ (hint: остаток - это всегда неотрицательное число)" 931 | ], 932 | "metadata": { 933 | "id": "A2CsekAmeJAU" 934 | } 935 | }, 936 | { 937 | "cell_type": "markdown", 938 | "source": [ 939 | "Возведение в степень:" 940 | ], 941 | "metadata": { 942 | "id": "spnlVYNIe3PT" 943 | } 944 | }, 945 | { 946 | "cell_type": "code", 947 | "source": [ 948 | "a = 5\n", 949 | "b = 2.2\n", 950 | "print(a ** b) ## с float тоже работает" 951 | ], 952 | "metadata": { 953 | "colab": { 954 | "base_uri": "https://localhost:8080/" 955 | }, 956 | "id": "27XOSsTLe292", 957 | "outputId": "782d5274-81c0-4c2c-fbb3-66cc2e1c3a3e" 958 | }, 959 | "execution_count": null, 960 | "outputs": [ 961 | { 962 | "output_type": "stream", 963 | "name": "stdout", 964 | "text": [ 965 | "34.493241536530384\n" 966 | ] 967 | } 968 | ] 969 | }, 970 | { 971 | "cell_type": "markdown", 972 | "source": [ 973 | "Отдельный бонус - всегда можно изменять уже текущую переменную, для этого достаточно сделать следующее:" 974 | ], 975 | "metadata": { 976 | "id": "97Fv4LGyfJQx" 977 | } 978 | }, 979 | { 980 | "cell_type": "code", 981 | "source": [ 982 | "a = 5\n", 983 | "b = 2\n", 984 | "a += b\n", 985 | "print(a)\n", 986 | "a -= b\n", 987 | "print(a)\n", 988 | "a *= b\n", 989 | "print(a)\n", 990 | "a //= b\n", 991 | "print(a)\n", 992 | "a **= b\n", 993 | "print(a)" 994 | ], 995 | "metadata": { 996 | "colab": { 997 | "base_uri": "https://localhost:8080/" 998 | }, 999 | "id": "BwlkZRMwfQHx", 1000 | "outputId": "4b9305b8-87cb-47f1-e6e9-8dd49880843d" 1001 | }, 1002 | "execution_count": null, 1003 | "outputs": [ 1004 | { 1005 | "output_type": "stream", 1006 | "name": "stdout", 1007 | "text": [ 1008 | "7\n", 1009 | "5\n", 1010 | "10\n", 1011 | "5\n", 1012 | "25\n" 1013 | ] 1014 | } 1015 | ] 1016 | }, 1017 | { 1018 | "cell_type": "markdown", 1019 | "source": [ 1020 | "### Списки" 1021 | ], 1022 | "metadata": { 1023 | "id": "zl8zLUoIgf0b" 1024 | } 1025 | }, 1026 | { 1027 | "cell_type": "markdown", 1028 | "source": [ 1029 | "Что такое список? Это некоторая упорядоченная последовательность элементов, каждый из которых имеет свой порядковый номер (или **индекс**). Скорее всего, в других ЯП вы также их могли видеть (например vector в C++)\n", 1030 | "\n", 1031 | "Списки инициализируются с помощью квадратных скобок, какиз-то ограничений на то, что все элементы должны быть одного типа, нет. Давайте на примере:" 1032 | ], 1033 | "metadata": { 1034 | "id": "SL_Z053dsVw9" 1035 | } 1036 | }, 1037 | { 1038 | "cell_type": "code", 1039 | "source": [ 1040 | "a = [1, 2, 3, 3.1415]\n", 1041 | "print(a)" 1042 | ], 1043 | "metadata": { 1044 | "colab": { 1045 | "base_uri": "https://localhost:8080/" 1046 | }, 1047 | "id": "vBDzp7qYs_7c", 1048 | "outputId": "b3d8e6fc-b6e0-4777-9df5-2c9f0379452d" 1049 | }, 1050 | "execution_count": null, 1051 | "outputs": [ 1052 | { 1053 | "output_type": "stream", 1054 | "name": "stdout", 1055 | "text": [ 1056 | "[1, 2, 3, 3.1415]\n" 1057 | ] 1058 | } 1059 | ] 1060 | }, 1061 | { 1062 | "cell_type": "code", 1063 | "source": [ 1064 | "## Нумерация идет с нуля! Также поддерживаются отрицательные индексы (считаем будто с конца)\n", 1065 | "\n", 1066 | "print(a[0], type(a[0]))\n", 1067 | "print(a[-1], type(a[-1]))" 1068 | ], 1069 | "metadata": { 1070 | "colab": { 1071 | "base_uri": "https://localhost:8080/" 1072 | }, 1073 | "id": "pYrZP038tD7h", 1074 | "outputId": "88bb990d-e319-4312-d655-5086563fd330" 1075 | }, 1076 | "execution_count": null, 1077 | "outputs": [ 1078 | { 1079 | "output_type": "stream", 1080 | "name": "stdout", 1081 | "text": [ 1082 | "1 \n", 1083 | "3.1415 \n" 1084 | ] 1085 | } 1086 | ] 1087 | }, 1088 | { 1089 | "cell_type": "markdown", 1090 | "source": [ 1091 | "Супер! Мы умеем итерироваться по списку (проходить по нему) более изощренными способами. Допустим, что мы хотим вывести только четные элементы, как же это сделать?" 1092 | ], 1093 | "metadata": { 1094 | "id": "Ulf-KHJ8tPJT" 1095 | } 1096 | }, 1097 | { 1098 | "cell_type": "code", 1099 | "source": [ 1100 | "a = [1, 2, 3, 3.1415]\n", 1101 | "a[::2] #Хоба!" 1102 | ], 1103 | "metadata": { 1104 | "colab": { 1105 | "base_uri": "https://localhost:8080/" 1106 | }, 1107 | "id": "ufbZZ6EvyqSv", 1108 | "outputId": "34c819ff-0ff0-482b-f400-c43293eb21cb" 1109 | }, 1110 | "execution_count": null, 1111 | "outputs": [ 1112 | { 1113 | "output_type": "execute_result", 1114 | "data": { 1115 | "text/plain": [ 1116 | "[1, 3]" 1117 | ] 1118 | }, 1119 | "metadata": {}, 1120 | "execution_count": 30 1121 | } 1122 | ] 1123 | }, 1124 | { 1125 | "cell_type": "markdown", 1126 | "source": [ 1127 | "Общая структура индексации:\n", 1128 | "\n", 1129 | "$$a[i:j::k]$$\n", 1130 | "\n", 1131 | "Переводим на русский:\n", 1132 | "\n", 1133 | "Возьми элементы с i-го (включительно) по j-ый (невключительно) с шагом k\n", 1134 | "\n", 1135 | "Попробуйте придумать как вытащить только нечетные элементы" 1136 | ], 1137 | "metadata": { 1138 | "id": "-mrASeG8yycQ" 1139 | } 1140 | }, 1141 | { 1142 | "cell_type": "markdown", 1143 | "source": [ 1144 | "Помним о том, что список - это по сути контейнер, где в каждом ящичке хранится свое собственное значение, а значит, его можно изменять! (опять-таки с помощью индексации)" 1145 | ], 1146 | "metadata": { 1147 | "id": "pe-EPu3lzfPt" 1148 | } 1149 | }, 1150 | { 1151 | "cell_type": "code", 1152 | "source": [ 1153 | "a[0] = 15\n", 1154 | "print(a)" 1155 | ], 1156 | "metadata": { 1157 | "colab": { 1158 | "base_uri": "https://localhost:8080/" 1159 | }, 1160 | "id": "ylS7V4AszqOD", 1161 | "outputId": "10ed1222-7407-4616-8a2b-cf004c4ac189" 1162 | }, 1163 | "execution_count": null, 1164 | "outputs": [ 1165 | { 1166 | "output_type": "stream", 1167 | "name": "stdout", 1168 | "text": [ 1169 | "[15, 2, 3, 3.1415]\n" 1170 | ] 1171 | } 1172 | ] 1173 | }, 1174 | { 1175 | "cell_type": "markdown", 1176 | "source": [ 1177 | "А допустим, что мы хотим не изменить, а что-то добавить. Как это сделать? С помощью метода append():" 1178 | ], 1179 | "metadata": { 1180 | "id": "msf66yajzyCj" 1181 | } 1182 | }, 1183 | { 1184 | "cell_type": "code", 1185 | "source": [ 1186 | "a = [1, 2, 3, 3.1415]\n", 1187 | "a.append(4) #если хотим добавить только 1 элемент\n", 1188 | "print(a)\n", 1189 | "a.extend([1, 2, 3]) # если хотим добавить сразу несколько элементов\n", 1190 | "print(a)\n", 1191 | "print(a + [1, 2, 3]) # а еще можно вот так" 1192 | ], 1193 | "metadata": { 1194 | "colab": { 1195 | "base_uri": "https://localhost:8080/" 1196 | }, 1197 | "id": "IXFfCwEiz3TT", 1198 | "outputId": "75f29f93-3c9f-46af-c8fc-ab8d0374bbb0" 1199 | }, 1200 | "execution_count": null, 1201 | "outputs": [ 1202 | { 1203 | "output_type": "stream", 1204 | "name": "stdout", 1205 | "text": [ 1206 | "[1, 2, 3, 3.1415, 4]\n", 1207 | "[1, 2, 3, 3.1415, 4, 1, 2, 3]\n", 1208 | "[1, 2, 3, 3.1415, 4, 1, 2, 3, 1, 2, 3]\n" 1209 | ] 1210 | } 1211 | ] 1212 | }, 1213 | { 1214 | "cell_type": "markdown", 1215 | "source": [ 1216 | "А еще можно продублировать с помощью умножения!" 1217 | ], 1218 | "metadata": { 1219 | "id": "oF_Ry2D33TK3" 1220 | } 1221 | }, 1222 | { 1223 | "cell_type": "code", 1224 | "source": [ 1225 | "a * 3" 1226 | ], 1227 | "metadata": { 1228 | "colab": { 1229 | "base_uri": "https://localhost:8080/" 1230 | }, 1231 | "id": "3XwvJqSC3WGO", 1232 | "outputId": "a9142248-6e22-4a38-8e23-cddfa175060a" 1233 | }, 1234 | "execution_count": null, 1235 | "outputs": [ 1236 | { 1237 | "output_type": "execute_result", 1238 | "data": { 1239 | "text/plain": [ 1240 | "[1, 1, 2, 2, 3, 3, 3.1415, 1, 1, 2, 2, 3, 3, 3.1415, 1, 1, 2, 2, 3, 3, 3.1415]" 1241 | ] 1242 | }, 1243 | "metadata": {}, 1244 | "execution_count": 50 1245 | } 1246 | ] 1247 | }, 1248 | { 1249 | "cell_type": "markdown", 1250 | "source": [ 1251 | "А теперь представим, что мы хотим добавить не в конец, а допустим, в середину. Так тоже умеем, но для этого нужен insert(num, elem) - добавь на позицию num элемент elem" 1252 | ], 1253 | "metadata": { 1254 | "id": "B7b0iOwe0m-4" 1255 | } 1256 | }, 1257 | { 1258 | "cell_type": "code", 1259 | "source": [ 1260 | "a.insert(1, -15)\n", 1261 | "print(a)" 1262 | ], 1263 | "metadata": { 1264 | "colab": { 1265 | "base_uri": "https://localhost:8080/" 1266 | }, 1267 | "id": "EUt-QY5V0yVJ", 1268 | "outputId": "7d517b7b-d53e-4fbb-b6b8-53b2799419a4" 1269 | }, 1270 | "execution_count": null, 1271 | "outputs": [ 1272 | { 1273 | "output_type": "stream", 1274 | "name": "stdout", 1275 | "text": [ 1276 | "[1, -15, 2, 3, 3.1415, 4, 1, 2, 3]\n" 1277 | ] 1278 | } 1279 | ] 1280 | }, 1281 | { 1282 | "cell_type": "markdown", 1283 | "source": [ 1284 | "Ну окей, мы чет много всего добавили, настало время удалять. Удалять можно несколькими способами:\n", 1285 | "\n", 1286 | "* pop(num) - удали элемент и верни его (num - с какой позиции забрать, если не указываем, то будет последний)\n", 1287 | "\n", 1288 | "* remove(elem) - удаляем по элементу. Берет первое вхождение и удаляет его\n", 1289 | "\n", 1290 | "* clear() - очистить весь список" 1291 | ], 1292 | "metadata": { 1293 | "id": "sY8kYa3V01aw" 1294 | } 1295 | }, 1296 | { 1297 | "cell_type": "code", 1298 | "source": [ 1299 | "print(a)\n", 1300 | "print(a.pop())\n", 1301 | "print(a)" 1302 | ], 1303 | "metadata": { 1304 | "colab": { 1305 | "base_uri": "https://localhost:8080/" 1306 | }, 1307 | "id": "3_KOZ5Ry00XR", 1308 | "outputId": "0e658f43-c8c9-4923-bb5b-4880d9a0f472" 1309 | }, 1310 | "execution_count": null, 1311 | "outputs": [ 1312 | { 1313 | "output_type": "stream", 1314 | "name": "stdout", 1315 | "text": [ 1316 | "[1, -15, 2, 3, 3.1415, 4, 1, 2, 3]\n", 1317 | "3\n", 1318 | "[1, -15, 2, 3, 3.1415, 4, 1, 2]\n" 1319 | ] 1320 | } 1321 | ] 1322 | }, 1323 | { 1324 | "cell_type": "code", 1325 | "source": [ 1326 | "a.remove(1)\n", 1327 | "print(a)\n", 1328 | "a.remove(1000) # если элемента нет, то выведет ошибку\n", 1329 | "print(a)" 1330 | ], 1331 | "metadata": { 1332 | "colab": { 1333 | "base_uri": "https://localhost:8080/", 1334 | "height": 260 1335 | }, 1336 | "id": "0rWuoQIg1frm", 1337 | "outputId": "83b12d2d-3443-4f97-ba31-9c9f8e4e616d" 1338 | }, 1339 | "execution_count": null, 1340 | "outputs": [ 1341 | { 1342 | "output_type": "stream", 1343 | "name": "stdout", 1344 | "text": [ 1345 | "[-15, 2, 3, 3.1415, 4, 2]\n" 1346 | ] 1347 | }, 1348 | { 1349 | "output_type": "error", 1350 | "ename": "ValueError", 1351 | "evalue": "ignored", 1352 | "traceback": [ 1353 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1354 | "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", 1355 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mremove\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mremove\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 1356 | "\u001b[0;31mValueError\u001b[0m: list.remove(x): x not in list" 1357 | ] 1358 | } 1359 | ] 1360 | }, 1361 | { 1362 | "cell_type": "code", 1363 | "source": [ 1364 | "a.clear()\n", 1365 | "print(a)\n", 1366 | "a = [1, 2, 3, 3.1415]" 1367 | ], 1368 | "metadata": { 1369 | "colab": { 1370 | "base_uri": "https://localhost:8080/" 1371 | }, 1372 | "id": "KqLHyLaw1pDI", 1373 | "outputId": "3961e895-efa4-4db2-a046-bdd78718051a" 1374 | }, 1375 | "execution_count": null, 1376 | "outputs": [ 1377 | { 1378 | "output_type": "stream", 1379 | "name": "stdout", 1380 | "text": [ 1381 | "[]\n" 1382 | ] 1383 | } 1384 | ] 1385 | }, 1386 | { 1387 | "cell_type": "markdown", 1388 | "source": [ 1389 | "Что еще умеем делать со списками?\n", 1390 | "\n", 1391 | "* len(l) - вывести размер списка (сколько элементов содержит)\n", 1392 | "\n", 1393 | "* count(elem) - посчитай, сколько раз элемент входит в список\n", 1394 | "\n", 1395 | "* index(elem) - выведи индекс первого вхождения элемента (если элемента нет, то выведет ошибку)\n", 1396 | "\n", 1397 | "* reverse() - переверни список\n", 1398 | "\n", 1399 | "* sort(reverse=False) - отсортируй список (по возрастанию, если поставить reverse=True, то будет по убыванию). Аналогично есть функция sorted(), которая делает то же самое, но только не меняет список\n", 1400 | "\n", 1401 | "* max/min(a) - найти максимум/минимум в списке" 1402 | ], 1403 | "metadata": { 1404 | "id": "ulKM1FGH1xVR" 1405 | } 1406 | }, 1407 | { 1408 | "cell_type": "code", 1409 | "source": [ 1410 | "a = [1, 2, 3, 3.1415, 1, 2, 3]\n", 1411 | "print(len(a))\n", 1412 | "print(a.count(2))\n", 1413 | "a.reverse()\n", 1414 | "print(a)\n", 1415 | "a.sort()\n", 1416 | "print(sorted(a, reverse=True), a)" 1417 | ], 1418 | "metadata": { 1419 | "colab": { 1420 | "base_uri": "https://localhost:8080/" 1421 | }, 1422 | "id": "SrBPAnq-1_Rd", 1423 | "outputId": "d452af5d-8b14-4068-ec29-1b1efe63db68" 1424 | }, 1425 | "execution_count": null, 1426 | "outputs": [ 1427 | { 1428 | "output_type": "stream", 1429 | "name": "stdout", 1430 | "text": [ 1431 | "7\n", 1432 | "2\n", 1433 | "[3, 2, 1, 3.1415, 3, 2, 1]\n", 1434 | "[3.1415, 3, 3, 2, 2, 1, 1] [1, 1, 2, 2, 3, 3, 3.1415]\n" 1435 | ] 1436 | } 1437 | ] 1438 | }, 1439 | { 1440 | "cell_type": "markdown", 1441 | "source": [ 1442 | "### Строки" 1443 | ], 1444 | "metadata": { 1445 | "id": "LKo9G3grfr4n" 1446 | } 1447 | }, 1448 | { 1449 | "cell_type": "markdown", 1450 | "source": [ 1451 | "Любое ввод, который мы сделаем, является строкой (string - это по сути последовательность символов). Если мы хотим самостоятельно ввести строку, то она должна быть в одинарных или двойных кавычках (для Python это одно и то же, главное, чтобы начало и конец совпадали)" 1452 | ], 1453 | "metadata": { 1454 | "id": "IqhrncS7f1vn" 1455 | } 1456 | }, 1457 | { 1458 | "cell_type": "code", 1459 | "source": [ 1460 | "s = \"4594520\"\n", 1461 | "print(type(s))" 1462 | ], 1463 | "metadata": { 1464 | "colab": { 1465 | "base_uri": "https://localhost:8080/" 1466 | }, 1467 | "id": "qRm9Z2vZfvP0", 1468 | "outputId": "d065d4f3-548e-423c-a5a3-c9415722f347" 1469 | }, 1470 | "execution_count": null, 1471 | "outputs": [ 1472 | { 1473 | "output_type": "stream", 1474 | "name": "stdout", 1475 | "text": [ 1476 | "\n" 1477 | ] 1478 | } 1479 | ] 1480 | }, 1481 | { 1482 | "cell_type": "markdown", 1483 | "source": [ 1484 | "Если говорить по-простому, то строка - это список из символов. А это значит, что операции индексации, сложения и умножения, о которых мы говорили, работают!" 1485 | ], 1486 | "metadata": { 1487 | "id": "gEvmNW6q3LsK" 1488 | } 1489 | }, 1490 | { 1491 | "cell_type": "code", 1492 | "source": [ 1493 | "print(s[::2])\n", 1494 | "print(s + \"123\")\n", 1495 | "print(s * 2)" 1496 | ], 1497 | "metadata": { 1498 | "colab": { 1499 | "base_uri": "https://localhost:8080/" 1500 | }, 1501 | "id": "g5F_6WW93ZnB", 1502 | "outputId": "c5da5ced-2fb2-4a84-8e3d-040542f85a4e" 1503 | }, 1504 | "execution_count": null, 1505 | "outputs": [ 1506 | { 1507 | "output_type": "stream", 1508 | "name": "stdout", 1509 | "text": [ 1510 | "4950\n", 1511 | "4594520123\n", 1512 | "45945204594520\n" 1513 | ] 1514 | } 1515 | ] 1516 | }, 1517 | { 1518 | "cell_type": "markdown", 1519 | "source": [ 1520 | "А вот с методами сложнее (это же все-таки другой тип данных). Что умеем?\n", 1521 | "\n", 1522 | "Методов и функций у string достаточно много (можно все найти [вот тут](https://docs.python.org/3/library/stdtypes.html#string-methods)), перечислим только самые важные из них:\n", 1523 | "\n", 1524 | "* len(s) - выведи длину строки\n", 1525 | "\n", 1526 | "* s.count(ss) - посчитать число подстрок внутри строки (считаем максимально по-простому, без пересечений)\n", 1527 | "\n", 1528 | "* s.find(ss), s.rfind(ss) - найти первое вхождение подстроки в строке (выводит индекс первого вхождения, если нет, то выводит -1)\n", 1529 | "\n", 1530 | "* s.isdigit() - проверка, являются ли все элементы в строке числами (можно использовать для проверки конвертации строки в число)\n", 1531 | "\n", 1532 | "* s.islower(), s.isupper() - проверка, являются ли все буквы заглавными или строчными\n", 1533 | "\n", 1534 | "* join() - соединить список строк в одну строку\n", 1535 | "\n", 1536 | "* s.strip(ss) - удалить все символы из строки ss в s\n", 1537 | "\n", 1538 | "* s.replace(s_a, s_b) - заменить подстроку s_a на s_b\n", 1539 | "\n", 1540 | "* s.split(ss) - разбить по подстроке ss строку s (если ничего не указано, то разобьет просто по пробелам)" 1541 | ], 1542 | "metadata": { 1543 | "id": "rTZ-1gUF3swo" 1544 | } 1545 | }, 1546 | { 1547 | "cell_type": "markdown", 1548 | "source": [ 1549 | "Многа букаф, пробуем:" 1550 | ], 1551 | "metadata": { 1552 | "id": "pY9_Y21pi992" 1553 | } 1554 | }, 1555 | { 1556 | "cell_type": "code", 1557 | "source": [ 1558 | "s = 'I love python (maybe)'\n", 1559 | "s_1 = '1234'\n", 1560 | "\n", 1561 | "print(len(s))\n", 1562 | "print(len(s_1))" 1563 | ], 1564 | "metadata": { 1565 | "colab": { 1566 | "base_uri": "https://localhost:8080/" 1567 | }, 1568 | "id": "2_joodmkjAfr", 1569 | "outputId": "f8dad7e3-126e-4c8e-9772-40504b5f7775" 1570 | }, 1571 | "execution_count": null, 1572 | "outputs": [ 1573 | { 1574 | "output_type": "stream", 1575 | "name": "stdout", 1576 | "text": [ 1577 | "21\n", 1578 | "4\n" 1579 | ] 1580 | } 1581 | ] 1582 | }, 1583 | { 1584 | "cell_type": "code", 1585 | "source": [ 1586 | "print(s.count('o'))\n", 1587 | "print(s.find(\"love\"))\n", 1588 | "print(s.rfind('o'))\n", 1589 | "print(s.find('-'))\n", 1590 | "print(s.isdigit(), s_1.isdigit())\n", 1591 | "print(s.islower(), s.isupper())\n", 1592 | "full_s = ' '.join([s, s_1])\n", 1593 | "print(full_s)\n", 1594 | "print(full_s.split())" 1595 | ], 1596 | "metadata": { 1597 | "colab": { 1598 | "base_uri": "https://localhost:8080/" 1599 | }, 1600 | "id": "FCEtSAQCjKYx", 1601 | "outputId": "50657ec2-d22e-4fee-897a-c5e6aca6073c" 1602 | }, 1603 | "execution_count": null, 1604 | "outputs": [ 1605 | { 1606 | "output_type": "stream", 1607 | "name": "stdout", 1608 | "text": [ 1609 | "2\n", 1610 | "2\n", 1611 | "11\n", 1612 | "-1\n", 1613 | "False True\n", 1614 | "False False\n", 1615 | "I love python (maybe) 1234\n", 1616 | "['I', 'love', 'python', '(maybe)', '1234']\n" 1617 | ] 1618 | } 1619 | ] 1620 | }, 1621 | { 1622 | "cell_type": "markdown", 1623 | "source": [ 1624 | "### Кортежи" 1625 | ], 1626 | "metadata": { 1627 | "id": "KWlJocc0gj8T" 1628 | } 1629 | }, 1630 | { 1631 | "cell_type": "markdown", 1632 | "source": [ 1633 | "Такой же фрукт, что и список, но под другим соусом. В чем разница: кортеж - **неизменяемый тип данных** (в отличие от списка). Зачем это нужно? Поговорим, когда будем обсуждать словари и множества\n", 1634 | "\n", 1635 | "Что значит неизменяемый? Давайте пробовать:" 1636 | ], 1637 | "metadata": { 1638 | "id": "y1lk5xPt4U4B" 1639 | } 1640 | }, 1641 | { 1642 | "cell_type": "code", 1643 | "source": [ 1644 | "a = (1, 2, 3) #создается с помощью круглых скобок или же tuple()\n", 1645 | "print(a[-1])" 1646 | ], 1647 | "metadata": { 1648 | "colab": { 1649 | "base_uri": "https://localhost:8080/" 1650 | }, 1651 | "id": "yBjyQNbi4l1t", 1652 | "outputId": "fcf3871b-2ed2-4199-9ce1-9811d6d3d1d9" 1653 | }, 1654 | "execution_count": null, 1655 | "outputs": [ 1656 | { 1657 | "output_type": "stream", 1658 | "name": "stdout", 1659 | "text": [ 1660 | "3\n" 1661 | ] 1662 | } 1663 | ] 1664 | }, 1665 | { 1666 | "cell_type": "markdown", 1667 | "source": [ 1668 | "Синтаксис такой же, но давайте попробуем изменить значение элемента:" 1669 | ], 1670 | "metadata": { 1671 | "id": "HJ4Sh6AH4sNN" 1672 | } 1673 | }, 1674 | { 1675 | "cell_type": "code", 1676 | "source": [ 1677 | "a[1] = 15" 1678 | ], 1679 | "metadata": { 1680 | "colab": { 1681 | "base_uri": "https://localhost:8080/", 1682 | "height": 185 1683 | }, 1684 | "id": "lZbEYvOE4vob", 1685 | "outputId": "d511ffa2-179e-4e4f-ddf2-36d9b97a3d74" 1686 | }, 1687 | "execution_count": null, 1688 | "outputs": [ 1689 | { 1690 | "output_type": "error", 1691 | "ename": "TypeError", 1692 | "evalue": "ignored", 1693 | "traceback": [ 1694 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1695 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 1696 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m15\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 1697 | "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" 1698 | ] 1699 | } 1700 | ] 1701 | }, 1702 | { 1703 | "cell_type": "markdown", 1704 | "source": [ 1705 | "Опа, мы не можем изменять сами значения! То есть по сути, это более жесткий вариант списка. Нет никакого append, изменния элементов, сортировки и вообще всего, что может изменить tuple. Единственное, что остается, это конкатенация (операция +)" 1706 | ], 1707 | "metadata": { 1708 | "id": "JWzC5_F94yEc" 1709 | } 1710 | }, 1711 | { 1712 | "cell_type": "code", 1713 | "source": [ 1714 | "a = (1, 2, 3)\n", 1715 | "b = (4, 5, 6)\n", 1716 | "a + b # изменить сам tuple нельзя, он создает просто новый tuple" 1717 | ], 1718 | "metadata": { 1719 | "colab": { 1720 | "base_uri": "https://localhost:8080/" 1721 | }, 1722 | "id": "eE_KLGqr5Dp-", 1723 | "outputId": "01298b29-f4fc-4e3c-e01e-b11abd38be68" 1724 | }, 1725 | "execution_count": null, 1726 | "outputs": [ 1727 | { 1728 | "output_type": "execute_result", 1729 | "data": { 1730 | "text/plain": [ 1731 | "(1, 2, 3, 4, 5, 6)" 1732 | ] 1733 | }, 1734 | "metadata": {}, 1735 | "execution_count": 57 1736 | } 1737 | ] 1738 | }, 1739 | { 1740 | "cell_type": "markdown", 1741 | "source": [ 1742 | "Что можно делать? Все, что можно было в списке, но что не меняет сам список:\n", 1743 | "\n", 1744 | "* len() - длина\n", 1745 | "\n", 1746 | "* count() - подсчет элементов\n", 1747 | "\n", 1748 | "* index() - индекс элемента (если он есть)" 1749 | ], 1750 | "metadata": { 1751 | "id": "CvjSmJRz5Ghc" 1752 | } 1753 | }, 1754 | { 1755 | "cell_type": "markdown", 1756 | "source": [ 1757 | "### Приведение типов" 1758 | ], 1759 | "metadata": { 1760 | "id": "qarkDDHT5dM2" 1761 | } 1762 | }, 1763 | { 1764 | "cell_type": "markdown", 1765 | "source": [ 1766 | "Итак, у нас есть разные типы данных, и хотелось бы, чтобы один можно было приводить к другому (например, мы считали данные, это строка. Но мы знаем, что там число, хотим число!)\n", 1767 | "\n", 1768 | "По сути можно привести к нужному типу данных с помощью вызова следующих функций (таким же образом можно и инициализировать, если нужно что-то более конкретное):\n", 1769 | "\n", 1770 | "* int() - приведи к целому числу\n", 1771 | "\n", 1772 | "* float() - приведи к вещественному числу\n", 1773 | "\n", 1774 | "* string() - приведи к строке\n", 1775 | "\n", 1776 | "* list() - приведи к списку\n", 1777 | "\n", 1778 | "* tuple() - приведи к кортежу\n", 1779 | "\n", 1780 | "* bool() - приведи к логической переменной\n", 1781 | "\n", 1782 | "Если нельзя привести - то естественно, выведет ошибку)" 1783 | ], 1784 | "metadata": { 1785 | "id": "oV1NutBn5lwA" 1786 | } 1787 | }, 1788 | { 1789 | "cell_type": "code", 1790 | "source": [ 1791 | "# Пример строки\n", 1792 | "\n", 1793 | "a = '52'\n", 1794 | "print(int(a), float(a), list(a), tuple(a), bool(a))" 1795 | ], 1796 | "metadata": { 1797 | "colab": { 1798 | "base_uri": "https://localhost:8080/" 1799 | }, 1800 | "id": "vvIiKi1z6H75", 1801 | "outputId": "59049dd9-a342-45ae-f37a-74b5d3c54212" 1802 | }, 1803 | "execution_count": null, 1804 | "outputs": [ 1805 | { 1806 | "output_type": "stream", 1807 | "name": "stdout", 1808 | "text": [ 1809 | "52 52.0 ['5', '2'] ('5', '2') True\n" 1810 | ] 1811 | } 1812 | ] 1813 | }, 1814 | { 1815 | "cell_type": "markdown", 1816 | "source": [ 1817 | "Что к чему нельзя привести?\n", 1818 | "\n", 1819 | "* string -> int, float (если это не число)\n", 1820 | "\n", 1821 | "Остальное в целом можно, но некоторые кейсы - на свой страх и риск)" 1822 | ], 1823 | "metadata": { 1824 | "id": "7ViQXj196bcA" 1825 | } 1826 | }, 1827 | { 1828 | "cell_type": "code", 1829 | "source": [ 1830 | "a = '5,6'\n", 1831 | "print(float(a)) #ВАЖНО! Числа с плавающей точкой должны иметь точку, а не запятую" 1832 | ], 1833 | "metadata": { 1834 | "colab": { 1835 | "base_uri": "https://localhost:8080/", 1836 | "height": 204 1837 | }, 1838 | "id": "LELuY8gA6wIJ", 1839 | "outputId": "dd1b260b-21fe-4c63-d585-232fff9457bd" 1840 | }, 1841 | "execution_count": null, 1842 | "outputs": [ 1843 | { 1844 | "output_type": "error", 1845 | "ename": "ValueError", 1846 | "evalue": "ignored", 1847 | "traceback": [ 1848 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1849 | "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", 1850 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'5,6'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 1851 | "\u001b[0;31mValueError\u001b[0m: could not convert string to float: '5,6'" 1852 | ] 1853 | } 1854 | ] 1855 | }, 1856 | { 1857 | "cell_type": "markdown", 1858 | "source": [ 1859 | "## Логические операторы" 1860 | ], 1861 | "metadata": { 1862 | "id": "O7OiFziPgydH" 1863 | } 1864 | }, 1865 | { 1866 | "cell_type": "markdown", 1867 | "source": [ 1868 | "Теперь у нас есть типы данных, с которыми можно проделывать различные операции. Теперь следующий вопрос, который, скорее всего, возникает: а как их сравнивать?\n", 1869 | "\n", 1870 | "С числами все более-менее понятно как сравнивать: одно больше, одно меньше (также есть операции больше или равно, меньше или равно etc)" 1871 | ], 1872 | "metadata": { 1873 | "id": "MTP635FpOyWT" 1874 | } 1875 | }, 1876 | { 1877 | "cell_type": "markdown", 1878 | "source": [ 1879 | "На самом деле сравнивать можно все типы данных внутри себя (то есть можно сравнивать списки, строки, числа etc, но только между собой). Если попробовать сранить друг с другом разные типы, то вам честно выдаст ошибку\n", 1880 | "\n", 1881 | "Как происходит сравнение?\n", 1882 | "\n", 1883 | "* Числа - тут все понятно, условное понятие больше-меньше берется в первую очередь из чисел\n", 1884 | "\n", 1885 | "* Строки сравниваются с помощью лексикографического порядка (то есть берется по символам, если один символ больше другого, то здесь все заканчивается и одна строка больше другой. В противном случае все продолжается до последнего символа)\n", 1886 | "\n", 1887 | "* Списки сравниваются поэлементно (логика как в строках)\n", 1888 | "\n", 1889 | "Давайте рассмотрим на примерах:" 1890 | ], 1891 | "metadata": { 1892 | "id": "nF-0KkPKPTpw" 1893 | } 1894 | }, 1895 | { 1896 | "cell_type": "code", 1897 | "source": [ 1898 | "a = 1\n", 1899 | "b = 2\n", 1900 | "c = 1\n", 1901 | "\n", 1902 | "print(a > b) # больше\n", 1903 | "print(a >= c) # больше или равно\n", 1904 | "print(a < b) # меньше\n", 1905 | "print(a <= c) # меньше или равно\n", 1906 | "print(a == c) # равенство (обратите внимание - два знака равно)\n", 1907 | "print(a != b) # неравенство" 1908 | ], 1909 | "metadata": { 1910 | "id": "FUaYjfRBPJxC" 1911 | }, 1912 | "execution_count": null, 1913 | "outputs": [] 1914 | }, 1915 | { 1916 | "cell_type": "markdown", 1917 | "source": [ 1918 | "Окей, у нас есть одно логическое выражение (сравнили). А можно ли несколько? Конечно можно! Для этого есть слова:\n", 1919 | "\n", 1920 | "* and - логическое И\n", 1921 | "\n", 1922 | "* or - логическое ИЛИ\n", 1923 | "\n", 1924 | "* not - логическое НЕ" 1925 | ], 1926 | "metadata": { 1927 | "id": "C7wW4fDjRYKg" 1928 | } 1929 | }, 1930 | { 1931 | "cell_type": "code", 1932 | "source": [ 1933 | "print(a == c and 0 == 0)\n", 1934 | "print(a != c or a != b)\n", 1935 | "print(not a)" 1936 | ], 1937 | "metadata": { 1938 | "colab": { 1939 | "base_uri": "https://localhost:8080/" 1940 | }, 1941 | "id": "fy28v_P0RknG", 1942 | "outputId": "b64c96a7-8ccb-4130-daf7-c6a8e5247dfd" 1943 | }, 1944 | "execution_count": null, 1945 | "outputs": [ 1946 | { 1947 | "output_type": "stream", 1948 | "name": "stdout", 1949 | "text": [ 1950 | "True\n", 1951 | "True\n", 1952 | "False\n" 1953 | ] 1954 | } 1955 | ] 1956 | }, 1957 | { 1958 | "cell_type": "markdown", 1959 | "source": [ 1960 | "## Заключение" 1961 | ], 1962 | "metadata": { 1963 | "id": "lTPVCHAFSmBr" 1964 | } 1965 | }, 1966 | { 1967 | "cell_type": "markdown", 1968 | "source": [ 1969 | "Итак, что успели разобрать:\n", 1970 | "\n", 1971 | "* Ввод-вывод данных\n", 1972 | "\n", 1973 | "* Типы данных в Python (какие есть, как с ними можно работать)\n", 1974 | "\n", 1975 | "* Логические операторы\n", 1976 | "\n", 1977 | "А теперь давайте решим один из вопросов, который возник в процессе: а как все-таким считать одновременно несколько чисел?\n", 1978 | "\n", 1979 | "А вот так:" 1980 | ], 1981 | "metadata": { 1982 | "id": "3cnXx97_S2CC" 1983 | } 1984 | }, 1985 | { 1986 | "cell_type": "code", 1987 | "source": [ 1988 | "a, b = map(int, input().split()) #да, так можно сделать с несколькими переменными одновременно\n", 1989 | "h = list(map(int, input().split()))\n", 1990 | "print(a, b, type(a), type(b))\n", 1991 | "print(h, type(h))" 1992 | ], 1993 | "metadata": { 1994 | "colab": { 1995 | "base_uri": "https://localhost:8080/" 1996 | }, 1997 | "id": "hS3P3h7STJP2", 1998 | "outputId": "b48a23b3-5aec-410e-8052-b29077d341cd" 1999 | }, 2000 | "execution_count": null, 2001 | "outputs": [ 2002 | { 2003 | "output_type": "stream", 2004 | "name": "stdout", 2005 | "text": [ 2006 | "4 4 \n", 2007 | "5 6\n", 2008 | "4 4 \n", 2009 | "[5, 6] \n" 2010 | ] 2011 | } 2012 | ] 2013 | }, 2014 | { 2015 | "cell_type": "markdown", 2016 | "source": [ 2017 | "Давайте разберем по частям:\n", 2018 | "\n", 2019 | "* map(f, l) - функция, которая применяет к каждому элементу из l функцию f (в данном случае - функция приведения к целому числу)\n", 2020 | "\n", 2021 | "* input().split() - считываем строку и делим на отдельные элементы с помощью split()\n", 2022 | "\n", 2023 | "* list() - приводим к списку (поскольку map выдает объект типа map)" 2024 | ], 2025 | "metadata": { 2026 | "id": "knxnqmkiUAkK" 2027 | } 2028 | }, 2029 | { 2030 | "cell_type": "markdown", 2031 | "source": [ 2032 | "## Животное дня" 2033 | ], 2034 | "metadata": { 2035 | "id": "omYnbJiPUZmL" 2036 | } 2037 | }, 2038 | { 2039 | "cell_type": "markdown", 2040 | "source": [ 2041 | "![](https://avatars.dzeninfra.ru/get-zen_doc/3638148/pub_6294a3f700cde16d532b1a0d_6294b6e57faaea548e24ebbe/scale_1200)" 2042 | ], 2043 | "metadata": { 2044 | "id": "Qw4sSS4kVRDa" 2045 | } 2046 | }, 2047 | { 2048 | "cell_type": "markdown", 2049 | "source": [ 2050 | "А это какапо, самый большой попугай на Земле. А еще он нелетающий (крылья у него есть, он с их помощью плюхается с деревьев иногда, но нет, он не умеет летать). Они очень забавные, приятно пахнут, и очень привыкают к людям :з\n", 2051 | "\n", 2052 | "Они ведут ночной образ жизни и по сути заменяли млекопитающих на островах Новой Зеландии, но из-за всяких кошек, горностаев и прочих животных, привезенных извне, был почти истреблен. Сейчас их всего 200 особей, которые обитают на специально изолированных островах\n", 2053 | "\n", 2054 | "Но хорошая новость в том, что за последние года их стало больше и они вполне неплохо себе живут :)" 2055 | ], 2056 | "metadata": { 2057 | "id": "J0NOKi6RU10v" 2058 | } 2059 | } 2060 | ] 2061 | } -------------------------------------------------------------------------------- /Lecture_2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "collapsed_sections": [ 8 | "x_wsFhcdI1GU", 9 | "5TL3Z4SwJfFt", 10 | "hqKOOk1dF3wg", 11 | "QSmFKIOlIJQr", 12 | "TQ69xxImpg6l", 13 | "FX3khP32WldB" 14 | ] 15 | }, 16 | "kernelspec": { 17 | "name": "python3", 18 | "display_name": "Python 3" 19 | }, 20 | "language_info": { 21 | "name": "python" 22 | } 23 | }, 24 | "cells": [ 25 | { 26 | "cell_type": "markdown", 27 | "source": [ 28 | "## Python-1, Лекция 2\n", 29 | "\n", 30 | "Лектор: Петров Тимур" 31 | ], 32 | "metadata": { 33 | "id": "MvjKDalaISGI" 34 | } 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "source": [ 39 | "Итак, сегодня мы поговорим про циклы, условия, контекстный менеджер, а также про ввод-вывод из файла" 40 | ], 41 | "metadata": { 42 | "id": "TLiKHi_0IYCm" 43 | } 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "source": [ 48 | "### Циклы и условия" 49 | ], 50 | "metadata": { 51 | "id": "x_wsFhcdI1GU" 52 | } 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "source": [ 57 | "Скорее всего в других ЯП вы сталкивались с классическими циклами и условиями:\n", 58 | "\n", 59 | "* if-else: если верно условие, то сделай одно, иначе сделай другое\n", 60 | "\n", 61 | "* while: пока верно условие, делай вот это\n", 62 | "\n", 63 | "* for: для каждого значения совершай действия\n", 64 | "\n", 65 | "В целом синтаксис Python не особо отличается от других ЯП в этом плане, но давайте глянем" 66 | ], 67 | "metadata": { 68 | "id": "13pzrwMKI3pk" 69 | } 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "source": [ 74 | "#### If-else" 75 | ], 76 | "metadata": { 77 | "id": "5TL3Z4SwJfFt" 78 | } 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "source": [ 83 | "Синтаксис следующий:\n", 84 | "\n", 85 | "```\n", 86 | "if :\n", 87 | " \n", 88 | "else:\n", 89 | " \n", 90 | "```" 91 | ], 92 | "metadata": { 93 | "id": "8ttX7CPpF8Wr" 94 | } 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "source": [ 99 | "Давайте на примере какой-нибудь простой задачи.\n", 100 | "\n", 101 | "Умный Петя придумал занимательную игру: если число делится на 3, то его надо умножить на 2 и прибавить 1. Если число делится на 5, то нужно вычесть 2 из числа. Если число делится на 7, то тогда надо взять от него остаток при делении на 15. В случае, если число делится на несколько делителей (например, на 3 и на 5), то тогда выполняется операция по самому наименьшему делителю. В случае, если число ни на что не делится, то тогда с ним ничего не происходит.\n", 102 | "\n", 103 | "Петя захотел сделать программу, которая выполняет эти нехитрые операции. Помогите ему это сделать" 104 | ], 105 | "metadata": { 106 | "id": "O7KOKreCJg6o" 107 | } 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "source": [ 112 | "Тут видно, что нужно применять условия (деление на 3, на 5 и на 7). Давайте пробовать с помощью if-else:" 113 | ], 114 | "metadata": { 115 | "id": "XZRYRSlnKa1F" 116 | } 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": null, 121 | "metadata": { 122 | "colab": { 123 | "base_uri": "https://localhost:8080/" 124 | }, 125 | "id": "EpCNTZqBHXlT", 126 | "outputId": "2ea25797-1d3a-4afb-a1c3-2b94653618b2" 127 | }, 128 | "outputs": [ 129 | { 130 | "output_type": "stream", 131 | "name": "stdout", 132 | "text": [ 133 | "Введите число:28\n", 134 | "13\n" 135 | ] 136 | } 137 | ], 138 | "source": [ 139 | "a = int(input(\"Введите число:\"))\n", 140 | "\n", 141 | "if (a % 3) == 0:\n", 142 | " a *= 2\n", 143 | " a += 1\n", 144 | "else:\n", 145 | " if (a % 5) == 0:\n", 146 | " a -= 2\n", 147 | " else:\n", 148 | " if (a % 7) == 0:\n", 149 | " a %= 15\n", 150 | "print(a)" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "source": [ 156 | "Вуаля, что-то получилось! Но выглядит немного громоздко: if-else заставляет постоянно делать переносы, такую программу читать сложнее.\n", 157 | "\n", 158 | "Но на это есть решение! Называется elif (else + if), он позволяет сделать несколько условий. Как это работает:\n", 159 | "\n", 160 | "```\n", 161 | "if condition_1: #если выполняется первое условие\n", 162 | " #сделай вот это, если будет condition_1\n", 163 | "elif condition_2: #если первое не выполняется, то проверяем на второе\n", 164 | " #сделай вот это, если будет condition_2\n", 165 | "else: # если оба условия неверны\n", 166 | " # делай вот это\n", 167 | "```" 168 | ], 169 | "metadata": { 170 | "id": "nmRP6sgoK3wl" 171 | } 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "source": [ 176 | "Попробуем переписать наш код:" 177 | ], 178 | "metadata": { 179 | "id": "F72swojaLpQV" 180 | } 181 | }, 182 | { 183 | "cell_type": "code", 184 | "source": [ 185 | "a = int(input(\"Введите число:\"))\n", 186 | "\n", 187 | "if (a % 3) == 0:\n", 188 | " a *= 2\n", 189 | " a += 1\n", 190 | "elif (a % 5) == 0:\n", 191 | " a -= 2\n", 192 | "elif (a % 7) == 0:\n", 193 | " a %= 15\n", 194 | "\n", 195 | "print(a)" 196 | ], 197 | "metadata": { 198 | "colab": { 199 | "base_uri": "https://localhost:8080/" 200 | }, 201 | "id": "UKxtDAnjLoVU", 202 | "outputId": "720e3693-371d-4b80-f5b0-0c5019e16810" 203 | }, 204 | "execution_count": null, 205 | "outputs": [ 206 | { 207 | "output_type": "stream", 208 | "name": "stdout", 209 | "text": [ 210 | "Введите число:28\n", 211 | "13\n" 212 | ] 213 | } 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "source": [ 219 | "Ура, выглядит гораздо проще и лучше!\n", 220 | "\n", 221 | "А теперь давайте попробуем вот такой пример:\n", 222 | "\n", 223 | "По введенной стране вывести ее столицу (допустим, что словарей мы не знаем, поэтмоу будем придумывать новые способы)\n", 224 | "\n", 225 | "Решим задачу с помощью if-else:" 226 | ], 227 | "metadata": { 228 | "id": "PlmWtVUcL1JR" 229 | } 230 | }, 231 | { 232 | "cell_type": "code", 233 | "source": [ 234 | "c = input(\"Enter any country:\")\n", 235 | "if c == \"Russia\":\n", 236 | " print(\"Moscow\")\n", 237 | "elif c == \"UK\":\n", 238 | " print(\"London is the capital of Great Britain\")\n", 239 | "elif c == \"USA\":\n", 240 | " print(\"My pronouns are U-S-A! 🦅\")\n", 241 | " print(\"Washington\")\n", 242 | "else:\n", 243 | " print(\"No lo se...\")" 244 | ], 245 | "metadata": { 246 | "colab": { 247 | "base_uri": "https://localhost:8080/" 248 | }, 249 | "id": "Ekn_tNtyRm0l", 250 | "outputId": "44812d11-448b-4add-9ffd-b856537ddd12" 251 | }, 252 | "execution_count": 1, 253 | "outputs": [ 254 | { 255 | "output_type": "stream", 256 | "name": "stdout", 257 | "text": [ 258 | "Enter any country:USA\n", 259 | "My pronouns are U-S-A! 🦅\n", 260 | "Washington\n" 261 | ] 262 | } 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "source": [ 268 | "Выглядит неплохо, однако каждый раз писать условие равенства... А давайте проще сделаем! Для этого есть такая вещь как match-case (появилась только в версии Python 3.10):" 269 | ], 270 | "metadata": { 271 | "id": "i3Tc8NoMSHI5" 272 | } 273 | }, 274 | { 275 | "cell_type": "code", 276 | "source": [ 277 | "c = input(\"Enter any country:\")\n", 278 | "match c:\n", 279 | " case \"Russia\":\n", 280 | " print(\"Moscow\")\n", 281 | " case \"UK\":\n", 282 | " print(\"London is the capital of Great Britain\")\n", 283 | " case \"USA\":\n", 284 | " print(\"My pronouns are U-S-A! 🦅\")\n", 285 | " print(\"Washington\")\n", 286 | " case _: ## обозначает else как все остальное\n", 287 | " print(\"No lo se...\")" 288 | ], 289 | "metadata": { 290 | "colab": { 291 | "base_uri": "https://localhost:8080/" 292 | }, 293 | "id": "lVOQUEl5SGqf", 294 | "outputId": "9936521c-0e46-485c-f3e0-61ac75f6770d" 295 | }, 296 | "execution_count": 2, 297 | "outputs": [ 298 | { 299 | "output_type": "stream", 300 | "name": "stdout", 301 | "text": [ 302 | "Enter any country:UK\n", 303 | "London is the capital of Great Britain\n" 304 | ] 305 | } 306 | ] 307 | }, 308 | { 309 | "cell_type": "markdown", 310 | "source": [ 311 | "Интересная штука, но так ее не так давно ввели, то вы ее редко увидите" 312 | ], 313 | "metadata": { 314 | "id": "3BXIW9t-Swry" 315 | } 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "source": [ 320 | "#### While" 321 | ], 322 | "metadata": { 323 | "id": "hqKOOk1dF3wg" 324 | } 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "source": [ 329 | "While - это уже цикл (то есть может выполняться несколько раз). В данном случае мы выполняем до тех пор, пока условие, которые мы задали, не станет ложным\n", 330 | "\n", 331 | "Синтаксис:\n", 332 | "\n", 333 | "```\n", 334 | "while :\n", 335 | " \n", 336 | "```\n", 337 | "\n", 338 | "То есть делай, пока можно. Когда нельзя - перестань. Давайте на примере:" 339 | ], 340 | "metadata": { 341 | "id": "WWJTqPFmF6xb" 342 | } 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "source": [ 347 | "Умному Пете понравился наш код, но он захотел сделать добавление к своей игре: он хочет, чтобы действия выполнялись до тех пор, пока число, пока число не будет делиться на 13 или пока мы не перестанем его менять. Помогите Пете усовершенствовать алгоритм" 348 | ], 349 | "metadata": { 350 | "id": "am5kZ2FIGaD2" 351 | } 352 | }, 353 | { 354 | "cell_type": "markdown", 355 | "source": [ 356 | "Итак, то есть нам необходимо менять число до тех пор, пока либо оно не будет не делиться на все вышеуказанные делители (то есть 3,5 и 7) или пока оно не станет делиться на 13. Давайте пробовать вначале с делением:" 357 | ], 358 | "metadata": { 359 | "id": "BfjRvkfiGyIl" 360 | } 361 | }, 362 | { 363 | "cell_type": "code", 364 | "source": [ 365 | "a = int(input(\"Введите число:\"))\n", 366 | "\n", 367 | "while (a % 13) != 0:\n", 368 | " if (a % 3) == 0:\n", 369 | " a *= 2\n", 370 | " a += 1\n", 371 | " elif (a % 5) == 0:\n", 372 | " a -= 2\n", 373 | " elif (a % 7) == 0:\n", 374 | " a %= 15\n", 375 | " a += 1\n", 376 | "\n", 377 | "print(a)" 378 | ], 379 | "metadata": { 380 | "colab": { 381 | "base_uri": "https://localhost:8080/", 382 | "height": 279 383 | }, 384 | "id": "VdqVrMm0HFjd", 385 | "outputId": "1e50e621-bf99-46ff-a6e7-57616eedd010" 386 | }, 387 | "execution_count": null, 388 | "outputs": [ 389 | { 390 | "name": "stdout", 391 | "output_type": "stream", 392 | "text": [ 393 | "Введите число:3\n" 394 | ] 395 | }, 396 | { 397 | "output_type": "error", 398 | "ename": "KeyboardInterrupt", 399 | "evalue": "ignored", 400 | "traceback": [ 401 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 402 | "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", 403 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;36m13\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m*=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 404 | "\u001b[0;31mKeyboardInterrupt\u001b[0m: " 405 | ] 406 | } 407 | ] 408 | }, 409 | { 410 | "cell_type": "markdown", 411 | "source": [ 412 | "Вроде бы все хорошо, но у нас нет условия, что ничего не изменилось... Как же его добавить?\n", 413 | "\n", 414 | "Для этого есть такие замечательные слова как continue или break. Как они работают?\n", 415 | "\n", 416 | "![](https://i.pinimg.com/736x/ef/48/cf/ef48cf48ec8fa615235c64a5e23ee731.jpg)" 417 | ], 418 | "metadata": { 419 | "id": "50xlA5I1HjhS" 420 | } 421 | }, 422 | { 423 | "cell_type": "code", 424 | "source": [ 425 | "a = int(input(\"Введите число:\"))\n", 426 | "\n", 427 | "while (a % 13) != 0:\n", 428 | " if (a % 3) == 0:\n", 429 | " a *= 2\n", 430 | " a += 1\n", 431 | " elif (a % 5) == 0:\n", 432 | " a -= 2\n", 433 | " elif (a % 7) == 0:\n", 434 | " a %= 15\n", 435 | " a += 1\n", 436 | " else:\n", 437 | " break\n", 438 | "\n", 439 | "print(a)" 440 | ], 441 | "metadata": { 442 | "colab": { 443 | "base_uri": "https://localhost:8080/" 444 | }, 445 | "id": "ZJzDM5CcH5_i", 446 | "outputId": "606bc1a7-e7e6-41c3-e619-02da8a2ac441" 447 | }, 448 | "execution_count": null, 449 | "outputs": [ 450 | { 451 | "output_type": "stream", 452 | "name": "stdout", 453 | "text": [ 454 | "Введите число:3\n", 455 | "8\n" 456 | ] 457 | } 458 | ] 459 | }, 460 | { 461 | "cell_type": "markdown", 462 | "source": [ 463 | "#### For" 464 | ], 465 | "metadata": { 466 | "id": "QSmFKIOlIJQr" 467 | } 468 | }, 469 | { 470 | "cell_type": "markdown", 471 | "source": [ 472 | "Все видели примерно вот такой синтаксис:\n", 473 | "\n", 474 | "```\n", 475 | "for i in range(0, 10):\n", 476 | " \n", 477 | "```\n", 478 | "\n", 479 | "Что обозначает: \"для каждого i от 0 до 9 сделай что-то\". Если обобщить, то это будет как:\n", 480 | "\n", 481 | "\"Для каждого элемента сделай вот это\" (такая формулировка нам еще пригодится)\n", 482 | "\n", 483 | "Что вообще в таком случае происходит?\n", 484 | "\n", 485 | "Есть переменная i, в которой будет храниться значение. В каждом шаге цикла у нас i меняется от самого первого значения (0) до самого последнего значения (9):" 486 | ], 487 | "metadata": { 488 | "id": "hDV_zHtOIMVh" 489 | } 490 | }, 491 | { 492 | "cell_type": "code", 493 | "source": [ 494 | "for i in range(0, 10):\n", 495 | " print(i)" 496 | ], 497 | "metadata": { 498 | "colab": { 499 | "base_uri": "https://localhost:8080/" 500 | }, 501 | "id": "9IB-CmBTWI-4", 502 | "outputId": "64dd9cf9-97a7-418f-e507-f025c428bbed" 503 | }, 504 | "execution_count": null, 505 | "outputs": [ 506 | { 507 | "output_type": "stream", 508 | "name": "stdout", 509 | "text": [ 510 | "0\n", 511 | "1\n", 512 | "2\n", 513 | "3\n", 514 | "4\n", 515 | "5\n", 516 | "6\n", 517 | "7\n", 518 | "8\n", 519 | "9\n" 520 | ] 521 | } 522 | ] 523 | }, 524 | { 525 | "cell_type": "markdown", 526 | "source": [ 527 | "Обратите внимание, что само i мы можем менять! Потому что каждый раз, когда мы заходим в for, значение обновляется (но так делать не надо, потому что это приводит к обфускации кода):" 528 | ], 529 | "metadata": { 530 | "id": "vZyRd_xCWZvJ" 531 | } 532 | }, 533 | { 534 | "cell_type": "code", 535 | "source": [ 536 | "for i in range(0, 10):\n", 537 | " i += 1\n", 538 | " print(i)" 539 | ], 540 | "metadata": { 541 | "colab": { 542 | "base_uri": "https://localhost:8080/" 543 | }, 544 | "id": "EW9JTGPaWhmI", 545 | "outputId": "1c93b1d3-b60a-4245-9c67-6542b1b06bf6" 546 | }, 547 | "execution_count": null, 548 | "outputs": [ 549 | { 550 | "output_type": "stream", 551 | "name": "stdout", 552 | "text": [ 553 | "1\n", 554 | "2\n", 555 | "3\n", 556 | "4\n", 557 | "5\n", 558 | "6\n", 559 | "7\n", 560 | "8\n", 561 | "9\n", 562 | "10\n" 563 | ] 564 | } 565 | ] 566 | }, 567 | { 568 | "cell_type": "markdown", 569 | "source": [ 570 | "Возвращаемся к Пете! Теперь он хочет знать, а какие значения получаться в итоге для всех четных чисел от 0 до 50. Давайте поможем ему!" 571 | ], 572 | "metadata": { 573 | "id": "G_JTeLgjWqD8" 574 | } 575 | }, 576 | { 577 | "cell_type": "code", 578 | "source": [ 579 | "for i in range(0, 51, 2):\n", 580 | " a = i\n", 581 | " while (a % 13) != 0:\n", 582 | " if (a % 3) == 0:\n", 583 | " a *= 2\n", 584 | " a += 1\n", 585 | " elif (a % 5) == 0:\n", 586 | " a -= 2\n", 587 | " elif (a % 7) == 0:\n", 588 | " a %= 15\n", 589 | " a += 1\n", 590 | " else:\n", 591 | " break\n", 592 | " print(i, a)" 593 | ], 594 | "metadata": { 595 | "id": "Mu4Uhi8iWxVL" 596 | }, 597 | "execution_count": null, 598 | "outputs": [] 599 | }, 600 | { 601 | "cell_type": "markdown", 602 | "source": [ 603 | "Вуаля! Давайте чуть-чуть посмотрим на range, что за зверь. Строго говоря это итератор (об этом мы поговорим на следующих лекциях). Он генерирует последовательность из чисел (можно соотнести с индексированием в списках и строках!)\n", 604 | "\n", 605 | "```\n", 606 | "range(beg, end, step) - выведи числа от числа beg до end (невключительно) с шагом step\n", 607 | "```" 608 | ], 609 | "metadata": { 610 | "id": "lgUYF2oMXCBZ" 611 | } 612 | }, 613 | { 614 | "cell_type": "code", 615 | "source": [ 616 | "print(list(range(0, 50, 2)))" 617 | ], 618 | "metadata": { 619 | "colab": { 620 | "base_uri": "https://localhost:8080/" 621 | }, 622 | "id": "O9QFWOhEXbbk", 623 | "outputId": "89b1275f-88ad-4dad-8ee7-e66654b537b1" 624 | }, 625 | "execution_count": null, 626 | "outputs": [ 627 | { 628 | "output_type": "stream", 629 | "name": "stdout", 630 | "text": [ 631 | "[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]\n" 632 | ] 633 | } 634 | ] 635 | }, 636 | { 637 | "cell_type": "markdown", 638 | "source": [ 639 | "Если говорить просто, то range предоставляет такой список, в котором мы и будем брать наши значения.\n", 640 | "\n", 641 | "А можно ли ходить не только по числам, но и как-нибудь еще? Конечно можно:" 642 | ], 643 | "metadata": { 644 | "id": "bwYIFbvfXgN_" 645 | } 646 | }, 647 | { 648 | "cell_type": "code", 649 | "source": [ 650 | "for i in \"abcds\":\n", 651 | " print(i)\n", 652 | "\n", 653 | "for i in [\"Hello\", \"World\"]:\n", 654 | " print(i)" 655 | ], 656 | "metadata": { 657 | "colab": { 658 | "base_uri": "https://localhost:8080/" 659 | }, 660 | "id": "eus_pEeDXq0l", 661 | "outputId": "2b116d3c-a041-46be-ac81-80d935e1fc6c" 662 | }, 663 | "execution_count": null, 664 | "outputs": [ 665 | { 666 | "output_type": "stream", 667 | "name": "stdout", 668 | "text": [ 669 | "a\n", 670 | "b\n", 671 | "c\n", 672 | "d\n", 673 | "s\n", 674 | "Hello\n", 675 | "World\n" 676 | ] 677 | } 678 | ] 679 | }, 680 | { 681 | "cell_type": "markdown", 682 | "source": [ 683 | "И последняя ремарка: так как for - это тоже цикл, то и слова continue и break действуют!" 684 | ], 685 | "metadata": { 686 | "id": "xFAUONrpX6-7" 687 | } 688 | }, 689 | { 690 | "cell_type": "code", 691 | "source": [ 692 | "for i in range(5):\n", 693 | " print(i)\n", 694 | " break\n", 695 | " print(i + 1)" 696 | ], 697 | "metadata": { 698 | "colab": { 699 | "base_uri": "https://localhost:8080/" 700 | }, 701 | "id": "iqepLQeyYAVL", 702 | "outputId": "cbde1dad-d8ed-47e2-f796-a7433fcc5fd4" 703 | }, 704 | "execution_count": null, 705 | "outputs": [ 706 | { 707 | "output_type": "stream", 708 | "name": "stdout", 709 | "text": [ 710 | "0\n" 711 | ] 712 | } 713 | ] 714 | }, 715 | { 716 | "cell_type": "code", 717 | "source": [ 718 | "for i in range(5):\n", 719 | " print(i)\n", 720 | " continue\n", 721 | " print(i + 1)" 722 | ], 723 | "metadata": { 724 | "colab": { 725 | "base_uri": "https://localhost:8080/" 726 | }, 727 | "id": "omkH6ULaYH1C", 728 | "outputId": "b6049944-455b-414a-fd4a-f0841db8ec62" 729 | }, 730 | "execution_count": null, 731 | "outputs": [ 732 | { 733 | "output_type": "stream", 734 | "name": "stdout", 735 | "text": [ 736 | "0\n", 737 | "1\n", 738 | "2\n", 739 | "3\n", 740 | "4\n" 741 | ] 742 | } 743 | ] 744 | }, 745 | { 746 | "cell_type": "markdown", 747 | "source": [ 748 | "И теперь еще немного про списки. Как бы нам легко и незайтеливо создать матрицу (то есть список списков)? Можно сделать с помощью операции умножения:" 749 | ], 750 | "metadata": { 751 | "id": "vbfxurIkS_yb" 752 | } 753 | }, 754 | { 755 | "cell_type": "code", 756 | "source": [ 757 | "a = [[0] * 5] * 5\n", 758 | "print(a)" 759 | ], 760 | "metadata": { 761 | "colab": { 762 | "base_uri": "https://localhost:8080/" 763 | }, 764 | "id": "u7WnpU8FTGCZ", 765 | "outputId": "da8d8208-c676-48d9-ab28-d613b9357aef" 766 | }, 767 | "execution_count": 17, 768 | "outputs": [ 769 | { 770 | "output_type": "stream", 771 | "name": "stdout", 772 | "text": [ 773 | "[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]\n" 774 | ] 775 | } 776 | ] 777 | }, 778 | { 779 | "cell_type": "code", 780 | "source": [ 781 | "a[0][0] = 5\n", 782 | "print(a)" 783 | ], 784 | "metadata": { 785 | "colab": { 786 | "base_uri": "https://localhost:8080/" 787 | }, 788 | "id": "b2bFJ-B9UBQc", 789 | "outputId": "08f0586d-989f-4edc-a053-9a42b5654e0e" 790 | }, 791 | "execution_count": 18, 792 | "outputs": [ 793 | { 794 | "output_type": "stream", 795 | "name": "stdout", 796 | "text": [ 797 | "[[5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0]]\n" 798 | ] 799 | } 800 | ] 801 | }, 802 | { 803 | "cell_type": "markdown", 804 | "source": [ 805 | "Упс, а эту проблему мы видели в прошлый раз. Почему так происходит? На самом деле Python играет с вами в игры:" 806 | ], 807 | "metadata": { 808 | "id": "ZMgke1MeUGBX" 809 | } 810 | }, 811 | { 812 | "cell_type": "code", 813 | "source": [ 814 | "for b in a:\n", 815 | " print(id(b)) ## позволяет понять расположение объекта" 816 | ], 817 | "metadata": { 818 | "colab": { 819 | "base_uri": "https://localhost:8080/" 820 | }, 821 | "id": "5zacVIIFUeg2", 822 | "outputId": "1a3572e5-e7dc-4ce0-8c8e-f24129dc1077" 823 | }, 824 | "execution_count": 19, 825 | "outputs": [ 826 | { 827 | "output_type": "stream", 828 | "name": "stdout", 829 | "text": [ 830 | "138016971300032\n", 831 | "138016971300032\n", 832 | "138016971300032\n", 833 | "138016971300032\n", 834 | "138016971300032\n" 835 | ] 836 | } 837 | ] 838 | }, 839 | { 840 | "cell_type": "markdown", 841 | "source": [ 842 | "Что он делает? Берет и не создает реальные копии, а просто создает ссылки на одну и ту же ячейку памяти, потому поведение такое\n", 843 | "\n", 844 | "Что же делать в данном случае? А все просто: нужно делать с помощью for!" 845 | ], 846 | "metadata": { 847 | "id": "cV3CA1TLUk2A" 848 | } 849 | }, 850 | { 851 | "cell_type": "code", 852 | "source": [ 853 | "a = [[0] * 5 for _ in range(5)]\n", 854 | "for b in a:\n", 855 | " print(id(b))\n", 856 | "\n", 857 | "a[0][0] = 5\n", 858 | "print(a)" 859 | ], 860 | "metadata": { 861 | "colab": { 862 | "base_uri": "https://localhost:8080/" 863 | }, 864 | "id": "SemtZYgUUzV6", 865 | "outputId": "dfcf880c-eb9c-405f-ac93-162cebb7a183" 866 | }, 867 | "execution_count": 27, 868 | "outputs": [ 869 | { 870 | "output_type": "stream", 871 | "name": "stdout", 872 | "text": [ 873 | "138018036605696\n", 874 | "138016972687744\n", 875 | "138016972699264\n", 876 | "138016972689216\n", 877 | "138016972347072\n", 878 | "[[5, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]\n" 879 | ] 880 | } 881 | ] 882 | }, 883 | { 884 | "cell_type": "markdown", 885 | "source": [ 886 | "С помощью for мы делаем так, что он каждый раз создает новый массив. Но тогда возникает вопрос: а почему для первого умножения так не надо делать?\n", 887 | "\n", 888 | "Опять-таки это связано с тем, какой у нас **объект**: изменяемый или нет (и вот про это будет в следующий раз)\n", 889 | "\n", 890 | "Если коротко: если объект **неизменяемый**, то любая операция порождает новый элемент. Такой пример показателен:" 891 | ], 892 | "metadata": { 893 | "id": "2LIlST00VOTi" 894 | } 895 | }, 896 | { 897 | "cell_type": "code", 898 | "source": [ 899 | "a = 1\n", 900 | "print(id(a))\n", 901 | "a += 2\n", 902 | "print(id(a))" 903 | ], 904 | "metadata": { 905 | "colab": { 906 | "base_uri": "https://localhost:8080/" 907 | }, 908 | "id": "GnY46SrsWB1_", 909 | "outputId": "9a55a022-782d-462b-ad7a-ec3a5d13e7e8" 910 | }, 911 | "execution_count": 29, 912 | "outputs": [ 913 | { 914 | "output_type": "stream", 915 | "name": "stdout", 916 | "text": [ 917 | "138018242740464\n", 918 | "138018242740528\n" 919 | ] 920 | } 921 | ] 922 | }, 923 | { 924 | "cell_type": "markdown", 925 | "source": [ 926 | "### Работа с файлами" 927 | ], 928 | "metadata": { 929 | "id": "TQ69xxImpg6l" 930 | } 931 | }, 932 | { 933 | "cell_type": "markdown", 934 | "source": [ 935 | "Иногда нам необходимо работать с файлами, потому что мы не всегда все вводим с помощью input (в целом вещь понятная - данные нам могут прийти в виде какого-нибудь текстового файлика, экселя, и так далее)\n", 936 | "\n", 937 | "И это все дело надо бы уметь читать\n", 938 | "\n", 939 | "![](https://www.meme-arsenal.com/memes/6ac45984c25a2230e62bfdf3d6d61e02.jpg)" 940 | ], 941 | "metadata": { 942 | "id": "J3MTrCaYpsnt" 943 | } 944 | }, 945 | { 946 | "cell_type": "markdown", 947 | "source": [ 948 | "Пойдем нелинейно: вначале научимся записывать файлы, а потом из них что-нибудь читать" 949 | ], 950 | "metadata": { 951 | "id": "JLwISW3Fq8rX" 952 | } 953 | }, 954 | { 955 | "cell_type": "code", 956 | "execution_count": null, 957 | "metadata": { 958 | "id": "3WnZqhDQoH87" 959 | }, 960 | "outputs": [], 961 | "source": [ 962 | "f = open(\"icantread.txt\", \"w\")\n", 963 | "# функция open состоит из двух аргументов:\n", 964 | "# 1 - сам файл (используем относительный путь файла)\n", 965 | "# 2 - mode (или же на что открываем файл)" 966 | ] 967 | }, 968 | { 969 | "cell_type": "markdown", 970 | "source": [ 971 | "Какие есть моды?\n", 972 | "\n", 973 | "* r - читаем файл (если файла нет, выдаст ошибку)\n", 974 | "\n", 975 | "* w - записываем файл (если файла нет, то создаст, но если файл был и мы что-то запишем, то прошлое сотрется)\n", 976 | "\n", 977 | "* a - записываем файл, добавляем в конец (не трогая предыдущее)\n", 978 | "\n", 979 | "* b - бинарный файл (про это попозже)" 980 | ], 981 | "metadata": { 982 | "id": "zacHBDR4rnPl" 983 | } 984 | }, 985 | { 986 | "cell_type": "markdown", 987 | "source": [ 988 | "#### Запись" 989 | ], 990 | "metadata": { 991 | "id": "ZPNZ51DBx19i" 992 | } 993 | }, 994 | { 995 | "cell_type": "markdown", 996 | "source": [ 997 | "Давайте что-нибудь запишем" 998 | ], 999 | "metadata": { 1000 | "id": "5dMOmIdaskBH" 1001 | } 1002 | }, 1003 | { 1004 | "cell_type": "code", 1005 | "source": [ 1006 | "text = '''\n", 1007 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n", 1008 | "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n", 1009 | "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n", 1010 | "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n", 1011 | "'''\n", 1012 | "\n", 1013 | "f.write(text) # с помощью write записываем\n", 1014 | "f.close()" 1015 | ], 1016 | "metadata": { 1017 | "id": "L9gJGu8rsmmn" 1018 | }, 1019 | "execution_count": null, 1020 | "outputs": [] 1021 | }, 1022 | { 1023 | "cell_type": "code", 1024 | "source": [ 1025 | "!cat icantread.txt #проверим через утилиту cat, есть ли там что-то" 1026 | ], 1027 | "metadata": { 1028 | "colab": { 1029 | "base_uri": "https://localhost:8080/" 1030 | }, 1031 | "id": "6464N8cOtA61", 1032 | "outputId": "9d006382-7bb4-4c26-bac7-8e84a60c02c8" 1033 | }, 1034 | "execution_count": null, 1035 | "outputs": [ 1036 | { 1037 | "output_type": "stream", 1038 | "name": "stdout", 1039 | "text": [ 1040 | "\n", 1041 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n", 1042 | "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n", 1043 | "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n", 1044 | "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n" 1045 | ] 1046 | } 1047 | ] 1048 | }, 1049 | { 1050 | "cell_type": "markdown", 1051 | "source": [ 1052 | "А еще умеем записывать с помощью print:" 1053 | ], 1054 | "metadata": { 1055 | "id": "NFNzv6hcy9L-" 1056 | } 1057 | }, 1058 | { 1059 | "cell_type": "code", 1060 | "source": [ 1061 | "print(\"Ahah\", file=open(\"new_file.txt\", \"w\"))" 1062 | ], 1063 | "metadata": { 1064 | "id": "aCkZ0CbIzA9y" 1065 | }, 1066 | "execution_count": null, 1067 | "outputs": [] 1068 | }, 1069 | { 1070 | "cell_type": "code", 1071 | "source": [ 1072 | "!cat new_file.txt" 1073 | ], 1074 | "metadata": { 1075 | "colab": { 1076 | "base_uri": "https://localhost:8080/" 1077 | }, 1078 | "id": "GPvtOTKZzB1g", 1079 | "outputId": "56e70b56-8f30-4398-8ca2-7d604b467978" 1080 | }, 1081 | "execution_count": null, 1082 | "outputs": [ 1083 | { 1084 | "output_type": "stream", 1085 | "name": "stdout", 1086 | "text": [ 1087 | "Ahah\n" 1088 | ] 1089 | } 1090 | ] 1091 | }, 1092 | { 1093 | "cell_type": "markdown", 1094 | "source": [ 1095 | "#### Чтение" 1096 | ], 1097 | "metadata": { 1098 | "id": "rJ_hsiaVxzpe" 1099 | } 1100 | }, 1101 | { 1102 | "cell_type": "code", 1103 | "source": [ 1104 | "f_new = open(\"icantread.txt\", 'r')\n", 1105 | "f_new.read() #читаем файл" 1106 | ], 1107 | "metadata": { 1108 | "colab": { 1109 | "base_uri": "https://localhost:8080/", 1110 | "height": 74 1111 | }, 1112 | "id": "ztiF8fEDtHuU", 1113 | "outputId": "43dc8386-fa39-45a7-ef57-566589d63619" 1114 | }, 1115 | "execution_count": null, 1116 | "outputs": [ 1117 | { 1118 | "output_type": "execute_result", 1119 | "data": { 1120 | "text/plain": [ 1121 | "'\\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\nUt enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\\nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\\nExcepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\\n'" 1122 | ], 1123 | "application/vnd.google.colaboratory.intrinsic+json": { 1124 | "type": "string" 1125 | } 1126 | }, 1127 | "metadata": {}, 1128 | "execution_count": 6 1129 | } 1130 | ] 1131 | }, 1132 | { 1133 | "cell_type": "markdown", 1134 | "source": [ 1135 | "Давайте попробуем прочесть еще раз:" 1136 | ], 1137 | "metadata": { 1138 | "id": "0DFKDfL8t8EH" 1139 | } 1140 | }, 1141 | { 1142 | "cell_type": "code", 1143 | "source": [ 1144 | "f_new.read()" 1145 | ], 1146 | "metadata": { 1147 | "colab": { 1148 | "base_uri": "https://localhost:8080/", 1149 | "height": 36 1150 | }, 1151 | "id": "MsRgr4uWt7pr", 1152 | "outputId": "4650f8a4-4079-4671-8222-d2f38415a8cd" 1153 | }, 1154 | "execution_count": null, 1155 | "outputs": [ 1156 | { 1157 | "output_type": "execute_result", 1158 | "data": { 1159 | "text/plain": [ 1160 | "''" 1161 | ], 1162 | "application/vnd.google.colaboratory.intrinsic+json": { 1163 | "type": "string" 1164 | } 1165 | }, 1166 | "metadata": {}, 1167 | "execution_count": 7 1168 | } 1169 | ] 1170 | }, 1171 | { 1172 | "cell_type": "markdown", 1173 | "source": [ 1174 | "А почему ничего нет?\n", 1175 | "\n", 1176 | "![](https://chpic.su/_data/stickers/b/blyadskiepapugi/blyadskiepapugi_016.webp)" 1177 | ], 1178 | "metadata": { 1179 | "id": "4yJI1El2uA99" 1180 | } 1181 | }, 1182 | { 1183 | "cell_type": "markdown", 1184 | "source": [ 1185 | "Дело в том, что чтение работает следующим образом:\n", 1186 | "\n", 1187 | "Мы по сути создаем бегунок, который проходит по файлу и его считывает поэлементно, двигая этот бегунок. И любой вызов read считывает всю эту часть и остается в конце\n", 1188 | "\n", 1189 | "Поэтому если вызвать два раза подряд, то во второй раз вы ничего не прочтете (бегунок сейчас не умеет назад), беда" 1190 | ], 1191 | "metadata": { 1192 | "id": "aBc21O2FuNMs" 1193 | } 1194 | }, 1195 | { 1196 | "cell_type": "markdown", 1197 | "source": [ 1198 | "Давайте научимся двигать бегунок так, как нам бы хотелось. За это отвечают:\n", 1199 | "\n", 1200 | "1. read(n) - прочитай n символов от места бегунка\n", 1201 | "\n", 1202 | "2. tell() - скажи, на каком мы сейчас символе\n", 1203 | "\n", 1204 | "3. seek(offset) - перейди на место offset относительно начала файла" 1205 | ], 1206 | "metadata": { 1207 | "id": "eT3EpY7Hu4jM" 1208 | } 1209 | }, 1210 | { 1211 | "cell_type": "code", 1212 | "source": [ 1213 | "with open(\"icantread.txt\", \"r\") as f: # с помощью with можно отдельно открыть файл и использовать его только внутри цикла, после цикла файл закроется\n", 1214 | " print(f.tell())\n", 1215 | " print(f.read(10)) #прочитай не весь текст, а только первые 10 символов\n", 1216 | " print(f.tell()) # скажи, на какой месте сейчас наш бегунок\n", 1217 | " print(f.seek(5)) #возьми начало файла и сдвинься на 5 символов\n", 1218 | " print(f.tell())\n", 1219 | " print(f.read(5))\n", 1220 | " print(f.tell())" 1221 | ], 1222 | "metadata": { 1223 | "colab": { 1224 | "base_uri": "https://localhost:8080/" 1225 | }, 1226 | "id": "e0MLeS2Su89a", 1227 | "outputId": "8671af80-5cc3-4ec9-fa65-e91c9553ac9e" 1228 | }, 1229 | "execution_count": null, 1230 | "outputs": [ 1231 | { 1232 | "output_type": "stream", 1233 | "name": "stdout", 1234 | "text": [ 1235 | "0\n", 1236 | "\n", 1237 | "Lorem ips\n", 1238 | "10\n", 1239 | "5\n", 1240 | "5\n", 1241 | "m ips\n", 1242 | "10\n", 1243 | "<_io.TextIOWrapper name='icantread.txt' mode='r' encoding='UTF-8'>\n" 1244 | ] 1245 | } 1246 | ] 1247 | }, 1248 | { 1249 | "cell_type": "markdown", 1250 | "source": [ 1251 | "А как двигаться не относительно начала файла, а относительно текущего места?" 1252 | ], 1253 | "metadata": { 1254 | "id": "C11PJlazxTUY" 1255 | } 1256 | }, 1257 | { 1258 | "cell_type": "code", 1259 | "source": [ 1260 | "with open(\"icantread.txt\", \"r\") as f:\n", 1261 | " print(f.read(10))\n", 1262 | " print(f.tell())\n", 1263 | " print(f.seek(f.tell() - 5)) #можно передавать просто сам tell!\n", 1264 | " print(f.tell())" 1265 | ], 1266 | "metadata": { 1267 | "colab": { 1268 | "base_uri": "https://localhost:8080/" 1269 | }, 1270 | "id": "VJvvSkxFxZC_", 1271 | "outputId": "09b63722-abae-4975-a7de-5f2bfbe49e8c" 1272 | }, 1273 | "execution_count": null, 1274 | "outputs": [ 1275 | { 1276 | "output_type": "stream", 1277 | "name": "stdout", 1278 | "text": [ 1279 | "\n", 1280 | "Lorem ips\n", 1281 | "10\n", 1282 | "5\n", 1283 | "5\n" 1284 | ] 1285 | } 1286 | ] 1287 | }, 1288 | { 1289 | "cell_type": "markdown", 1290 | "source": [ 1291 | "В чем еще видим проблему? В том, что у нас тут появились в качестве отдельных знаков перевод строки (вообще все такие знаки типа табов etc будут отображаться)\n", 1292 | "\n", 1293 | "А может попробуем по линиям прочитать?" 1294 | ], 1295 | "metadata": { 1296 | "id": "gnm9rFrQtVsr" 1297 | } 1298 | }, 1299 | { 1300 | "cell_type": "code", 1301 | "source": [ 1302 | "with open(\"icantread.txt\", \"r\") as f:\n", 1303 | " for line in f: # читает по линии до перевода строки\n", 1304 | " print(line.strip())\n", 1305 | " print('-' * 30)" 1306 | ], 1307 | "metadata": { 1308 | "colab": { 1309 | "base_uri": "https://localhost:8080/" 1310 | }, 1311 | "id": "SFGRADzpthdx", 1312 | "outputId": "c3e62d82-8956-4ef9-bb57-ffb7c3ab5358" 1313 | }, 1314 | "execution_count": null, 1315 | "outputs": [ 1316 | { 1317 | "output_type": "stream", 1318 | "name": "stdout", 1319 | "text": [ 1320 | "\n", 1321 | "------------------------------\n", 1322 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n", 1323 | "------------------------------\n", 1324 | "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n", 1325 | "------------------------------\n", 1326 | "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n", 1327 | "------------------------------\n", 1328 | "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n", 1329 | "------------------------------\n" 1330 | ] 1331 | } 1332 | ] 1333 | }, 1334 | { 1335 | "cell_type": "markdown", 1336 | "source": [ 1337 | "А еще умеем выводить просто с помощью print:\n" 1338 | ], 1339 | "metadata": { 1340 | "id": "B0SHqDXRycIQ" 1341 | } 1342 | }, 1343 | { 1344 | "cell_type": "markdown", 1345 | "source": [ 1346 | "#### Учимся печатать и читать из одного места" 1347 | ], 1348 | "metadata": { 1349 | "id": "3UVGsdQ_x-Fx" 1350 | } 1351 | }, 1352 | { 1353 | "cell_type": "code", 1354 | "source": [ 1355 | "fh = open('icantread.txt', 'r+') #w+ позволяет сразу и записывать, и читать\n", 1356 | "\n", 1357 | "fh.seek(11)\n", 1358 | "print(fh.read(5))\n", 1359 | "print(fh.tell())\n", 1360 | "fh.seek(11)\n", 1361 | "fh.write('WOWOWOWOWOWOO')\n", 1362 | "fh.seek(0)\n", 1363 | "content = fh.read()\n", 1364 | "print(content)\n", 1365 | "fh.close()" 1366 | ], 1367 | "metadata": { 1368 | "colab": { 1369 | "base_uri": "https://localhost:8080/" 1370 | }, 1371 | "id": "3Emr4O75zQYy", 1372 | "outputId": "c2ea52b4-82f6-4dc6-a0c2-e9c1a05c433b" 1373 | }, 1374 | "execution_count": null, 1375 | "outputs": [ 1376 | { 1377 | "output_type": "stream", 1378 | "name": "stdout", 1379 | "text": [ 1380 | "m dol\n", 1381 | "16\n", 1382 | "\n", 1383 | "Lorem ipsuWOWOWOWOWOWOOmet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n", 1384 | "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n", 1385 | "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n", 1386 | "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n", 1387 | "\n" 1388 | ] 1389 | } 1390 | ] 1391 | }, 1392 | { 1393 | "cell_type": "markdown", 1394 | "source": [ 1395 | "#### Заключение" 1396 | ], 1397 | "metadata": { 1398 | "id": "J3WZkyu4zfk3" 1399 | } 1400 | }, 1401 | { 1402 | "cell_type": "markdown", 1403 | "source": [ 1404 | "Умеем читать из файла, умеем записывать в файл, умеем читать и писать! В целом достаточно" 1405 | ], 1406 | "metadata": { 1407 | "id": "X447WveXzhGw" 1408 | } 1409 | }, 1410 | { 1411 | "cell_type": "markdown", 1412 | "source": [ 1413 | "![](https://img5.goodfon.ru/original/2048x2048/5/58/popugai-ptitsa-fon-vzgliad-kakadu-rozovyi-portret-boke.jpg)" 1414 | ], 1415 | "metadata": { 1416 | "id": "ibaZ45dbzs5s" 1417 | } 1418 | }, 1419 | { 1420 | "cell_type": "markdown", 1421 | "source": [ 1422 | "## Контекстные менеджеры" 1423 | ], 1424 | "metadata": { 1425 | "id": "FX3khP32WldB" 1426 | } 1427 | }, 1428 | { 1429 | "cell_type": "markdown", 1430 | "source": [ 1431 | "Что такое контекстный менеджер? Если отвечать максимально просто - то это оператор with\n", 1432 | "\n", 1433 | "Если более сложно (согласно PEP) - это объект, который реализует операторы enter и exit (про это детально будем говорить в части ООП)\n", 1434 | "\n", 1435 | "Как это выглядит?" 1436 | ], 1437 | "metadata": { 1438 | "id": "BevCyHGaWngk" 1439 | } 1440 | }, 1441 | { 1442 | "cell_type": "code", 1443 | "source": [ 1444 | "class FileManager():\n", 1445 | " def __init__(self, filename, mode):\n", 1446 | " self.filename = filename\n", 1447 | " self.mode = mode\n", 1448 | " self.file = None\n", 1449 | "\n", 1450 | " def __enter__(self):\n", 1451 | " self.file = open(self.filename, self.mode)\n", 1452 | " return self.file\n", 1453 | "\n", 1454 | " def __exit__(self, exc_type, exc_value, exc_traceback):\n", 1455 | " self.file.close()\n", 1456 | "\n", 1457 | "# loading a file\n", 1458 | "with FileManager('test.txt', 'w') as f:\n", 1459 | " f.write('Test')\n", 1460 | "\n", 1461 | "print(f.closed)" 1462 | ], 1463 | "metadata": { 1464 | "id": "3ZSzKG2BXqJE" 1465 | }, 1466 | "execution_count": null, 1467 | "outputs": [] 1468 | }, 1469 | { 1470 | "cell_type": "markdown", 1471 | "source": [ 1472 | "Примерно вот так (это способ реализации открытия и закрытия файла). Что здесь происходит:\n", 1473 | "\n", 1474 | "```\n", 1475 | "with : - инциализация контестного менеджера\n", 1476 | " - происходит enter\n", 1477 | " \n", 1478 | "-происходит exit\n", 1479 | "\n", 1480 | "```\n", 1481 | "\n", 1482 | "Как это работает с точки зрения файлов и почему with позволяет нам не закрывать файлы самостоятельно?\n", 1483 | "\n", 1484 | "Мы указываем в самом начале, что надо надо открыть или передать (в данном случае мы передаем файловый поток), как-то с ним работаем, а после закрытие прописано в самом exit() - то есть по выходу из блока он делает самостоятельное закрытие" 1485 | ], 1486 | "metadata": { 1487 | "id": "lol4lFX-XrTu" 1488 | } 1489 | }, 1490 | { 1491 | "cell_type": "markdown", 1492 | "source": [ 1493 | "## Попугай дня" 1494 | ], 1495 | "metadata": { 1496 | "id": "TmoSCQJttmJf" 1497 | } 1498 | }, 1499 | { 1500 | "cell_type": "markdown", 1501 | "source": [ 1502 | "![](https://upload.wikimedia.org/wikipedia/commons/2/2d/Nymphicus_hollandicus_-perching_on_wires_-Australia-6a.jpg)" 1503 | ], 1504 | "metadata": { 1505 | "id": "ItvjQcgqtv9J" 1506 | } 1507 | }, 1508 | { 1509 | "cell_type": "markdown", 1510 | "source": [ 1511 | "Это корелла. Вы, наверное, их часто видите в качестве домашних попугаев (исключая волнистых попугайчиков)\n", 1512 | "\n", 1513 | "Самое интересно - коррела это какаду. Вообще не ассоциируются с какаду, верно? Но это единственная маленькая какадушка\n", 1514 | "\n", 1515 | "Они бывают разных расцветок, но на картинке - натуральный окрас (однако их всегда отличает такая желтенькая голова и красные щечки)\n", 1516 | "\n", 1517 | "Они очень мелодичные, но не так хорошо говорят, как другие попугаи.\n", 1518 | "\n", 1519 | "И хотя правительство Австралии (где они живут вообще) запрещает вывоз корелл, их можно найти где угодно, потому что они легко размножаются и живут в неволе" 1520 | ], 1521 | "metadata": { 1522 | "id": "bAVmNBiRtyXN" 1523 | } 1524 | } 1525 | ] 1526 | } -------------------------------------------------------------------------------- /Lecture_3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [] 7 | }, 8 | "kernelspec": { 9 | "name": "python3", 10 | "display_name": "Python 3" 11 | }, 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "# Python-1, Лекция 3\n", 21 | "\n", 22 | "Лектор: Петров Тимур" 23 | ], 24 | "metadata": { 25 | "id": "8y5Q2vP2l0X7" 26 | } 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "source": [ 31 | "## Множества" 32 | ], 33 | "metadata": { 34 | "id": "dxa__Uzkl6D9" 35 | } 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "source": [ 40 | "Скорее всего вы знаете, что такое множества, исходя из математики. Множество - это набор уникальных элементов.\n", 41 | "\n", 42 | "Ну и что же в этом уникального, спросите вы? Можно же просто просто хранить список. А вот нет, тогда мы будем сильно проигрывать по времени. Давайте попробуем что-нибудь:" 43 | ], 44 | "metadata": { 45 | "id": "FjWXX3hfmUE-" 46 | } 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "metadata": { 52 | "id": "rjDejp-nlvX7" 53 | }, 54 | "outputs": [], 55 | "source": [ 56 | "a = [i for i in range(100000)]\n", 57 | "b = set(a) #создать множество можно из чего угодно" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "source": [ 63 | "%%time\n", 64 | "\n", 65 | "## Вот так можно замерить время\n", 66 | "\n", 67 | "c = 10000\n", 68 | "if c not in a:\n", 69 | " a.append(c)" 70 | ], 71 | "metadata": { 72 | "colab": { 73 | "base_uri": "https://localhost:8080/" 74 | }, 75 | "id": "crOsAtctoc_P", 76 | "outputId": "47e33982-8a31-40ea-a2f9-e02308c31a1d" 77 | }, 78 | "execution_count": null, 79 | "outputs": [ 80 | { 81 | "output_type": "stream", 82 | "name": "stdout", 83 | "text": [ 84 | "CPU times: user 184 µs, sys: 0 ns, total: 184 µs\n", 85 | "Wall time: 189 µs\n" 86 | ] 87 | } 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "source": [ 93 | "%%time\n", 94 | "\n", 95 | "## Вот так можно замерить время\n", 96 | "\n", 97 | "c = 10000\n", 98 | "if c not in b:\n", 99 | " b.add(c)" 100 | ], 101 | "metadata": { 102 | "colab": { 103 | "base_uri": "https://localhost:8080/" 104 | }, 105 | "id": "5wUdkU3popLs", 106 | "outputId": "ba959e17-3794-45de-e629-1b101a495132" 107 | }, 108 | "execution_count": null, 109 | "outputs": [ 110 | { 111 | "output_type": "stream", 112 | "name": "stdout", 113 | "text": [ 114 | "CPU times: user 6 µs, sys: 1 µs, total: 7 µs\n", 115 | "Wall time: 11.4 µs\n" 116 | ] 117 | } 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "source": [ 123 | "Опа и пожалуйста, экономия времени! Как это получается? На самом деле ответ кроется в том, как хранит элементы множество и список (список хранит просто в раличных ячейках памяти элементы, множество же занимается хэшированием, но про это вам расскажут на курсе алгоритмов)\n", 124 | "\n", 125 | "А наша задача, в первую очередь, это вообще понять, как с ними работать. Итак, поехали:" 126 | ], 127 | "metadata": { 128 | "id": "MSK31w6uo_au" 129 | } 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "source": [ 134 | "* s.add(elem) - добавить элемент во множество (если элемент уже есть, то ничего не изменится)\n", 135 | "\n", 136 | "* clear() - очистить множество\n", 137 | "\n", 138 | "* copy() - скопировать множество\n", 139 | "\n", 140 | "* s.discard(elem) / s.remove(elem) / s.pop() - разные методы удаления (первое - не ругнется, если попробовать убрать элемент не из множества, второй - ругнется, третий - просто вытаскивает рандомный элемент и возвращает его)\n", 141 | "\n", 142 | "* difference / difference_update() / - - разность\n", 143 | "\n", 144 | "* union() / | - объединение множеств\n", 145 | "\n", 146 | "* intersection() / & - пересечение множеств\n", 147 | "\n", 148 | "* issubset() / isdisjoint() / issuperset() - проверка на подмножество, наличие пересечений и проверка на супермножество\n", 149 | "\n", 150 | "* symmetric_difference / ^ - симметричная разность\n", 151 | "\n", 152 | "* len(s) - узнать число элементов во множестве\n", 153 | "\n", 154 | "Как можно заметить, некоторые операторы можно использовать даже)" 155 | ], 156 | "metadata": { 157 | "id": "Rey23DlopqgS" 158 | } 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "source": [ 163 | "![](https://tutorial.eyehunts.com/wp-content/uploads/2021/10/Python-set-operations.png)" 164 | ], 165 | "metadata": { 166 | "id": "Vy29pQMB-gCw" 167 | } 168 | }, 169 | { 170 | "cell_type": "code", 171 | "source": [ 172 | "a = {1,2,3,5} #а еще множества можно объявлять вот так\n", 173 | "b = {4,5,6}\n", 174 | "\n", 175 | "print(a.union(b), a | b)\n", 176 | "print(a.intersection(b), a & b)\n", 177 | "print(a.difference(b), a - b)\n", 178 | "print(a.symmetric_difference(b), a ^ b)" 179 | ], 180 | "metadata": { 181 | "colab": { 182 | "base_uri": "https://localhost:8080/" 183 | }, 184 | "id": "5j_PPmBLsyRM", 185 | "outputId": "2668a0ad-bccb-469a-a780-c044fb798f3b" 186 | }, 187 | "execution_count": null, 188 | "outputs": [ 189 | { 190 | "output_type": "stream", 191 | "name": "stdout", 192 | "text": [ 193 | "{1, 2, 3, 4, 5, 6} {1, 2, 3, 4, 5, 6}\n", 194 | "{5} {5}\n", 195 | "{1, 2, 3} {1, 2, 3}\n", 196 | "{1, 2, 3, 4, 6} {1, 2, 3, 4, 6}\n" 197 | ] 198 | } 199 | ] 200 | }, 201 | { 202 | "cell_type": "markdown", 203 | "source": [ 204 | "Есть такая штука, как difference_update. Как думаете, в чем разница?" 205 | ], 206 | "metadata": { 207 | "id": "cnnmDYxPtEiI" 208 | } 209 | }, 210 | { 211 | "cell_type": "code", 212 | "source": [ 213 | "print(a.difference(b), a)\n", 214 | "print(a.difference_update(b), a)" 215 | ], 216 | "metadata": { 217 | "colab": { 218 | "base_uri": "https://localhost:8080/" 219 | }, 220 | "id": "cAd-BBm2tKPj", 221 | "outputId": "60e0640a-2590-4dba-f6be-56d64848d977" 222 | }, 223 | "execution_count": null, 224 | "outputs": [ 225 | { 226 | "output_type": "stream", 227 | "name": "stdout", 228 | "text": [ 229 | "{1, 2, 3} {1, 2, 3, 5}\n", 230 | "None {1, 2, 3}\n" 231 | ] 232 | } 233 | ] 234 | }, 235 | { 236 | "cell_type": "markdown", 237 | "source": [ 238 | "Поиграемся с удалениями элементов:" 239 | ], 240 | "metadata": { 241 | "id": "G5wQ-6eNtULD" 242 | } 243 | }, 244 | { 245 | "cell_type": "code", 246 | "source": [ 247 | "a.discard(5)\n", 248 | "a.discard(5)\n", 249 | "a.remove(3)\n", 250 | "a.remove(3)" 251 | ], 252 | "metadata": { 253 | "colab": { 254 | "base_uri": "https://localhost:8080/", 255 | "height": 222 256 | }, 257 | "id": "upsQVq4ltTuw", 258 | "outputId": "1f29d9be-0be1-4d7b-cf74-671bdaea85c1" 259 | }, 260 | "execution_count": null, 261 | "outputs": [ 262 | { 263 | "output_type": "error", 264 | "ename": "KeyError", 265 | "evalue": "ignored", 266 | "traceback": [ 267 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 268 | "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", 269 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdiscard\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mremove\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mremove\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 270 | "\u001b[0;31mKeyError\u001b[0m: 3" 271 | ] 272 | } 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "source": [ 278 | "while a:\n", 279 | " print(a.pop())" 280 | ], 281 | "metadata": { 282 | "colab": { 283 | "base_uri": "https://localhost:8080/" 284 | }, 285 | "id": "0ion_mKAtfuk", 286 | "outputId": "1214623a-30a5-4674-f01b-f781fb41dd7f" 287 | }, 288 | "execution_count": null, 289 | "outputs": [ 290 | { 291 | "output_type": "stream", 292 | "name": "stdout", 293 | "text": [ 294 | "1\n", 295 | "2\n" 296 | ] 297 | } 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "source": [ 303 | "a.add([15,20]) #упс, а почему так нельзя?" 304 | ], 305 | "metadata": { 306 | "colab": { 307 | "base_uri": "https://localhost:8080/", 308 | "height": 185 309 | }, 310 | "id": "0uI-W9YqtjnX", 311 | "outputId": "7211a1d6-b48d-40ea-e664-a64f7688239e" 312 | }, 313 | "execution_count": null, 314 | "outputs": [ 315 | { 316 | "output_type": "error", 317 | "ename": "TypeError", 318 | "evalue": "ignored", 319 | "traceback": [ 320 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 321 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 322 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m15\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 323 | "\u001b[0;31mTypeError\u001b[0m: unhashable type: 'list'" 324 | ] 325 | } 326 | ] 327 | }, 328 | { 329 | "cell_type": "markdown", 330 | "source": [ 331 | "Как раз здесь нам значимо, что есть mutable и immutable типы данных. Как мы упоминали на первой лекции, отличие кортежа от списка в том, что одно - изменяемое, а другое - нет\n", 332 | "\n", 333 | "Это играет большую роль в случае с хэшированием. Изменяемые объекты не хешируемы! А это значит, что их нельзя хранить в множествах и словарях (в словарях - в качестве ключей). Почему? А потому что принцип их работы зависит от того условия, что объекты нельзя изменить (только таким образом это работает быстро и так, как надо).\n", 334 | "\n", 335 | "Ну хорошо, как же тогда быть? Использовать кортеж!" 336 | ], 337 | "metadata": { 338 | "id": "0gZegHentq-y" 339 | } 340 | }, 341 | { 342 | "cell_type": "code", 343 | "source": [ 344 | "a.add((15, 20))\n", 345 | "a" 346 | ], 347 | "metadata": { 348 | "colab": { 349 | "base_uri": "https://localhost:8080/" 350 | }, 351 | "id": "CpLkx6M2uQjB", 352 | "outputId": "70b24906-aa00-47bd-d67e-34415813bb69" 353 | }, 354 | "execution_count": null, 355 | "outputs": [ 356 | { 357 | "output_type": "execute_result", 358 | "data": { 359 | "text/plain": [ 360 | "{(15, 20)}" 361 | ] 362 | }, 363 | "metadata": {}, 364 | "execution_count": 29 365 | } 366 | ] 367 | }, 368 | { 369 | "cell_type": "markdown", 370 | "source": [ 371 | "Славно! А какие типы изменяемые, а какие нет? Давайте поделим:\n", 372 | "\n", 373 | "1. Изменяемые:\n", 374 | "\n", 375 | "* Списки\n", 376 | "\n", 377 | "* Множества\n", 378 | "\n", 379 | "* Словари\n", 380 | "\n", 381 | "2. Неизменяемые:\n", 382 | "\n", 383 | "* Строки\n", 384 | "\n", 385 | "* Кортежи\n", 386 | "\n", 387 | "* Числа\n", 388 | "\n", 389 | "* Логические значения" 390 | ], 391 | "metadata": { 392 | "id": "k1TktXf-uUh0" 393 | } 394 | }, 395 | { 396 | "cell_type": "markdown", 397 | "source": [ 398 | "Так что в целом не так все и плохо!" 399 | ], 400 | "metadata": { 401 | "id": "dKaa08oOu1Em" 402 | } 403 | }, 404 | { 405 | "cell_type": "markdown", 406 | "source": [ 407 | "### FrozenSet" 408 | ], 409 | "metadata": { 410 | "id": "DrBP9jP0mC9h" 411 | } 412 | }, 413 | { 414 | "cell_type": "markdown", 415 | "source": [ 416 | "А теперь то же самое, но только сделаем так, чтобы set был неизменяемым (иногда это нужно)" 417 | ], 418 | "metadata": { 419 | "id": "gq5UybUOmUlA" 420 | } 421 | }, 422 | { 423 | "cell_type": "code", 424 | "source": [ 425 | "a.add(frozenset({15, 20})) #жесть, так можно!\n", 426 | "a" 427 | ], 428 | "metadata": { 429 | "colab": { 430 | "base_uri": "https://localhost:8080/" 431 | }, 432 | "id": "C0yZOpxZmU8C", 433 | "outputId": "56d4bac9-cea7-412d-d1d3-c4936e30697d" 434 | }, 435 | "execution_count": null, 436 | "outputs": [ 437 | { 438 | "output_type": "execute_result", 439 | "data": { 440 | "text/plain": [ 441 | "{(15, 20), frozenset({15, 20})}" 442 | ] 443 | }, 444 | "metadata": {}, 445 | "execution_count": 30 446 | } 447 | ] 448 | }, 449 | { 450 | "cell_type": "markdown", 451 | "source": [ 452 | "Подерживает все те же операции, что и set, но которые его не меняют (нельзя изменить frozenset, на то он и нужен)" 453 | ], 454 | "metadata": { 455 | "id": "PA65csanvQxC" 456 | } 457 | }, 458 | { 459 | "cell_type": "markdown", 460 | "source": [ 461 | "## Словари" 462 | ], 463 | "metadata": { 464 | "id": "8Om1iSgAl76q" 465 | } 466 | }, 467 | { 468 | "cell_type": "markdown", 469 | "source": [ 470 | "Ну хорошо, у нас есть множества, давайте пойдем чуть дальше. Допустим, что мы хотим иметь не просто множество, а еще уметь и считать, сколько раз тот или иной элемент встретился!\n", 471 | "\n", 472 | "Можно ответить про Counter, конечно, но про это мы позже поговорим тоже, а сейчас давайте про уже встроенные методы. То есть что бы нам хотелось? Хранить некоторую пару \"value\" - \"значение\" (в нашем случае сколько раз встретилось)\n", 473 | "\n", 474 | "Вот для этого и подходят словари! (почему словарь - аналогия с переводом)\n", 475 | "Давайте создавать!" 476 | ], 477 | "metadata": { 478 | "id": "j0qa_qhjl9Mb" 479 | } 480 | }, 481 | { 482 | "cell_type": "code", 483 | "source": [ 484 | "d = {1:5, 2:6, 3:7} #явно объявить можно вот таким образом, так же существует просто вызов dict()\n", 485 | "d" 486 | ], 487 | "metadata": { 488 | "colab": { 489 | "base_uri": "https://localhost:8080/" 490 | }, 491 | "id": "DnI9IM0eDNZS", 492 | "outputId": "1e0db169-1fc6-4f9c-edc8-aa7140681f6b" 493 | }, 494 | "execution_count": null, 495 | "outputs": [ 496 | { 497 | "output_type": "execute_result", 498 | "data": { 499 | "text/plain": [ 500 | "{1: 5, 2: 6, 3: 7}" 501 | ] 502 | }, 503 | "metadata": {}, 504 | "execution_count": 31 505 | } 506 | ] 507 | }, 508 | { 509 | "cell_type": "markdown", 510 | "source": [ 511 | "Все, что находится слева (до двоеточия) - это ключи (или же keys), все, что после - это значения (или же values)" 512 | ], 513 | "metadata": { 514 | "id": "T1v9kuA0DeJx" 515 | } 516 | }, 517 | { 518 | "cell_type": "code", 519 | "source": [ 520 | "print(d.keys(), d.values(), d.items())" 521 | ], 522 | "metadata": { 523 | "colab": { 524 | "base_uri": "https://localhost:8080/" 525 | }, 526 | "id": "GveiZeqgDmbk", 527 | "outputId": "7c295883-40c4-4990-cab5-4ba8a615b46e" 528 | }, 529 | "execution_count": null, 530 | "outputs": [ 531 | { 532 | "output_type": "stream", 533 | "name": "stdout", 534 | "text": [ 535 | "dict_keys([1, 2, 3]) dict_values([5, 6, 7]) dict_items([(1, 5), (2, 6), (3, 7)])\n" 536 | ] 537 | } 538 | ] 539 | }, 540 | { 541 | "cell_type": "markdown", 542 | "source": [ 543 | "Как обращаться по ключу? Абсолютно точно также, как и в списке (можно считать, будто это индексы):" 544 | ], 545 | "metadata": { 546 | "id": "qXD2B436LE38" 547 | } 548 | }, 549 | { 550 | "cell_type": "code", 551 | "source": [ 552 | "d[3]" 553 | ], 554 | "metadata": { 555 | "colab": { 556 | "base_uri": "https://localhost:8080/" 557 | }, 558 | "id": "cFTSDgjwLMZ3", 559 | "outputId": "92c4dc15-84e7-49a4-a1f6-426a190c42fe" 560 | }, 561 | "execution_count": null, 562 | "outputs": [ 563 | { 564 | "output_type": "execute_result", 565 | "data": { 566 | "text/plain": [ 567 | "7" 568 | ] 569 | }, 570 | "metadata": {}, 571 | "execution_count": 39 572 | } 573 | ] 574 | }, 575 | { 576 | "cell_type": "markdown", 577 | "source": [ 578 | "Но потом мы попробовали вот так:" 579 | ], 580 | "metadata": { 581 | "id": "hEShj_o2LP0b" 582 | } 583 | }, 584 | { 585 | "cell_type": "code", 586 | "source": [ 587 | "d[4]" 588 | ], 589 | "metadata": { 590 | "colab": { 591 | "base_uri": "https://localhost:8080/", 592 | "height": 185 593 | }, 594 | "id": "k1W5X1fCLRw8", 595 | "outputId": "f72f0462-7c62-4f58-fee2-b20dd4e08ca9" 596 | }, 597 | "execution_count": null, 598 | "outputs": [ 599 | { 600 | "output_type": "error", 601 | "ename": "KeyError", 602 | "evalue": "ignored", 603 | "traceback": [ 604 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 605 | "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", 606 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 607 | "\u001b[0;31mKeyError\u001b[0m: 4" 608 | ] 609 | } 610 | ] 611 | }, 612 | { 613 | "cell_type": "markdown", 614 | "source": [ 615 | "И получили ошибку, что же делать? Для этого есть более \"безопасный\" вариант: get()" 616 | ], 617 | "metadata": { 618 | "id": "BwawQG1nLTIw" 619 | } 620 | }, 621 | { 622 | "cell_type": "code", 623 | "source": [ 624 | "print(d.get(4)) #он выведет ничего, так как ничего и нет" 625 | ], 626 | "metadata": { 627 | "colab": { 628 | "base_uri": "https://localhost:8080/" 629 | }, 630 | "id": "jYNw4kt5LZWu", 631 | "outputId": "c4be3751-6f82-4303-8dab-6e9e17634a54" 632 | }, 633 | "execution_count": null, 634 | "outputs": [ 635 | { 636 | "output_type": "stream", 637 | "name": "stdout", 638 | "text": [ 639 | "None\n" 640 | ] 641 | } 642 | ] 643 | }, 644 | { 645 | "cell_type": "markdown", 646 | "source": [ 647 | "Что можео быть в качестве значения? На самом деле что угодно!\n", 648 | "\n", 649 | "Что может быть в качестве ключей? Только НЕизменяемые объекты" 650 | ], 651 | "metadata": { 652 | "id": "H4jgBDeoLsAT" 653 | } 654 | }, 655 | { 656 | "cell_type": "code", 657 | "source": [ 658 | "a = {\"abc\": set([1,2,3])}\n", 659 | "a" 660 | ], 661 | "metadata": { 662 | "colab": { 663 | "base_uri": "https://localhost:8080/" 664 | }, 665 | "id": "eNUFhYv1LxxI", 666 | "outputId": "b8a2e327-3cc7-47f1-d6c3-5ddebe50f058" 667 | }, 668 | "execution_count": null, 669 | "outputs": [ 670 | { 671 | "output_type": "execute_result", 672 | "data": { 673 | "text/plain": [ 674 | "{'abc': {1, 2, 3}}" 675 | ] 676 | }, 677 | "metadata": {}, 678 | "execution_count": 44 679 | } 680 | ] 681 | }, 682 | { 683 | "cell_type": "markdown", 684 | "source": [ 685 | "Ну хорошо, создавать от руки мы умеем. А как теперь добавлять/удалять и так далее, что мы вообще можем делать со словарем?\n", 686 | "\n" 687 | ], 688 | "metadata": { 689 | "id": "NHUllYNKL54z" 690 | } 691 | }, 692 | { 693 | "cell_type": "code", 694 | "source": [ 695 | "d[4] = 100\n", 696 | "d[1] += 1\n", 697 | "print(d)" 698 | ], 699 | "metadata": { 700 | "colab": { 701 | "base_uri": "https://localhost:8080/" 702 | }, 703 | "id": "YcxE52x5MRQX", 704 | "outputId": "12959f6d-ea55-40f7-bd9d-77c3825b2e62" 705 | }, 706 | "execution_count": null, 707 | "outputs": [ 708 | { 709 | "output_type": "stream", 710 | "name": "stdout", 711 | "text": [ 712 | "{1: 6, 2: 6, 3: 7, 4: 100}\n" 713 | ] 714 | } 715 | ] 716 | }, 717 | { 718 | "cell_type": "markdown", 719 | "source": [ 720 | "* d.pop(elem) - удалить ключ и вернуть по нему значение\n", 721 | "\n", 722 | "* d.popitem() - удали рандомный элемент и верни ключ-значение удаленного\n", 723 | "\n", 724 | "* d.clear() - очистить словарь\n", 725 | "\n", 726 | "* len(d) - число элементов\n", 727 | "\n", 728 | "* d.setdefault(key, value) - поставь значение по ключу, если его нет, то поставь value" 729 | ], 730 | "metadata": { 731 | "id": "0WLRBamyRCI6" 732 | } 733 | }, 734 | { 735 | "cell_type": "code", 736 | "source": [ 737 | "d.pop(4)\n", 738 | "print(d.popitem())\n", 739 | "print(len(d))\n", 740 | "print(d.setdefault(4, 10000))\n", 741 | "print(d)" 742 | ], 743 | "metadata": { 744 | "colab": { 745 | "base_uri": "https://localhost:8080/" 746 | }, 747 | "id": "UsVyTCb7RgaE", 748 | "outputId": "3b9dddec-2a4a-4440-94e0-c9b4350197b7" 749 | }, 750 | "execution_count": null, 751 | "outputs": [ 752 | { 753 | "output_type": "stream", 754 | "name": "stdout", 755 | "text": [ 756 | "(3, 7)\n", 757 | "2\n", 758 | "10000\n" 759 | ] 760 | } 761 | ] 762 | }, 763 | { 764 | "cell_type": "code", 765 | "source": [ 766 | "d.clear()\n", 767 | "d" 768 | ], 769 | "metadata": { 770 | "colab": { 771 | "base_uri": "https://localhost:8080/" 772 | }, 773 | "id": "Di3vId6_R7vq", 774 | "outputId": "6b4a2871-5460-4716-8847-bcc8c48c5fe6" 775 | }, 776 | "execution_count": null, 777 | "outputs": [ 778 | { 779 | "output_type": "execute_result", 780 | "data": { 781 | "text/plain": [ 782 | "{}" 783 | ] 784 | }, 785 | "metadata": {}, 786 | "execution_count": 50 787 | } 788 | ] 789 | }, 790 | { 791 | "cell_type": "markdown", 792 | "source": [ 793 | "Ну хорошо, вроде как понятно, как работать со словарем. Но, допустим, к нам приходит отдел маркетинга и такой: хотим автоматизировать подсчет переходов по рекламе. У нас есть ЭКСЕЛЬКА, в которой есть список с рекламными компаниями и текущие значения, которые посчитали, а как добавить эту информацию и дальше считать по-новому?\n", 794 | "\n", 795 | "Мы призадумались..." 796 | ], 797 | "metadata": { 798 | "id": "wRBJSfX2L9aq" 799 | } 800 | }, 801 | { 802 | "cell_type": "code", 803 | "source": [ 804 | "c = [\"c_1\", \"c_2\", \"c_3\", \"c_4\", \"c_5\"]\n", 805 | "n = [1, 2, 3, 4, 100]\n", 806 | "\n", 807 | "## Что-то надо сделать" 808 | ], 809 | "metadata": { 810 | "id": "_P3AYUKDMbnK" 811 | }, 812 | "execution_count": null, 813 | "outputs": [] 814 | }, 815 | { 816 | "cell_type": "markdown", 817 | "source": [ 818 | "Можно было бы сделать вот так:" 819 | ], 820 | "metadata": { 821 | "id": "_ZpTnE8IMkX5" 822 | } 823 | }, 824 | { 825 | "cell_type": "code", 826 | "source": [ 827 | "d = dict()\n", 828 | "for i in range(len(c)):\n", 829 | " d[c[i]] = n[i]\n", 830 | "print(d)" 831 | ], 832 | "metadata": { 833 | "colab": { 834 | "base_uri": "https://localhost:8080/" 835 | }, 836 | "id": "DSOPdGFnMm8d", 837 | "outputId": "375040c4-cf59-4301-bb04-25fafaaaaa2f" 838 | }, 839 | "execution_count": null, 840 | "outputs": [ 841 | { 842 | "output_type": "stream", 843 | "name": "stdout", 844 | "text": [ 845 | "{'c_1': 1, 'c_2': 2, 'c_3': 3, 'c_4': 4, 'c_5': 100}\n" 846 | ] 847 | } 848 | ] 849 | }, 850 | { 851 | "cell_type": "markdown", 852 | "source": [ 853 | "Но можно ли не использовать циклы и сделать это более кратко?...\n", 854 | "\n", 855 | "А вот можно!" 856 | ], 857 | "metadata": { 858 | "id": "ta9xrCYHMuYt" 859 | } 860 | }, 861 | { 862 | "cell_type": "code", 863 | "source": [ 864 | "d = dict(zip(c, n))\n", 865 | "print(d)" 866 | ], 867 | "metadata": { 868 | "colab": { 869 | "base_uri": "https://localhost:8080/" 870 | }, 871 | "id": "6o4BKShbM1Tj", 872 | "outputId": "f9e9434d-66ce-4106-a819-163ac14326ea" 873 | }, 874 | "execution_count": null, 875 | "outputs": [ 876 | { 877 | "output_type": "stream", 878 | "name": "stdout", 879 | "text": [ 880 | "{'c_1': 1, 'c_2': 2, 'c_3': 3, 'c_4': 4, 'c_5': 100}\n" 881 | ] 882 | } 883 | ] 884 | }, 885 | { 886 | "cell_type": "markdown", 887 | "source": [ 888 | "Вау! А что случилось?\n", 889 | "\n", 890 | "Функция zip позволяет объединить данные в кортежи (аналогия с застежкой)" 891 | ], 892 | "metadata": { 893 | "id": "y_F_m87KM5yY" 894 | } 895 | }, 896 | { 897 | "cell_type": "code", 898 | "source": [ 899 | "list(zip(c, n)) ## приходится делать list, потому что zip создает итератор (но про это позже)" 900 | ], 901 | "metadata": { 902 | "colab": { 903 | "base_uri": "https://localhost:8080/" 904 | }, 905 | "id": "aoBvpIsFNK5r", 906 | "outputId": "77c8b0f3-fc48-4836-837c-3a990d6c3911" 907 | }, 908 | "execution_count": null, 909 | "outputs": [ 910 | { 911 | "output_type": "execute_result", 912 | "data": { 913 | "text/plain": [ 914 | "[('c_1', 1), ('c_2', 2), ('c_3', 3), ('c_4', 4), ('c_5', 100)]" 915 | ] 916 | }, 917 | "metadata": {}, 918 | "execution_count": 9 919 | } 920 | ] 921 | }, 922 | { 923 | "cell_type": "markdown", 924 | "source": [ 925 | "## DefaultDict" 926 | ], 927 | "metadata": { 928 | "id": "CtI2AsPzmFW1" 929 | } 930 | }, 931 | { 932 | "cell_type": "markdown", 933 | "source": [ 934 | "Итак, в чем самая главная проблема словарей? Ну банально в том, что нужно каждый раз проверять, а есть ли ключ в словаре, а то если его нет, то наш скрипт, само собой, упадет. А что, если бы мы прям с самого начал уже задавали какое-то базовое (дефолтное) значение? Вот для этого существует такая вещь, как defaultdict, которая лежит в отдельном модуле collections" 935 | ], 936 | "metadata": { 937 | "id": "DCFIpSSdmVX8" 938 | } 939 | }, 940 | { 941 | "cell_type": "markdown", 942 | "source": [ 943 | "Итак, сегодня мы в первый раз поговорим про библиотеки и модули. Что это такое?\n", 944 | "\n", 945 | "По сути библиотека - это набор дополнительных функций, которые позволяют вам использовать их с помощью вызова всего лишь одной строчки кода!" 946 | ], 947 | "metadata": { 948 | "id": "BMV6oSynJ0UJ" 949 | } 950 | }, 951 | { 952 | "cell_type": "code", 953 | "source": [ 954 | "import math # когда делаем вот так, то можно вызывать функции через название модуля.функция\n", 955 | "from numpy import * # импортим все и можем обращаться напрямую\n", 956 | "import matplotlib.pyplot as plt # даем сокращение названию модулю" 957 | ], 958 | "metadata": { 959 | "id": "MFF8mF_5J2K1" 960 | }, 961 | "execution_count": null, 962 | "outputs": [] 963 | }, 964 | { 965 | "cell_type": "markdown", 966 | "source": [ 967 | "Давайте попробуем импортировать [collections](https://docs.python.org/3/library/collections.html):" 968 | ], 969 | "metadata": { 970 | "id": "5uU3MPsjKCJj" 971 | } 972 | }, 973 | { 974 | "cell_type": "code", 975 | "source": [ 976 | "from collections import defaultdict\n", 977 | "\n", 978 | "d = defaultdict(int)\n", 979 | "print(d[10])" 980 | ], 981 | "metadata": { 982 | "colab": { 983 | "base_uri": "https://localhost:8080/" 984 | }, 985 | "id": "FqBuJwTSKTE3", 986 | "outputId": "d239747d-de29-4650-c34a-6a01e15d1d98" 987 | }, 988 | "execution_count": null, 989 | "outputs": [ 990 | { 991 | "output_type": "stream", 992 | "name": "stdout", 993 | "text": [ 994 | "0\n" 995 | ] 996 | } 997 | ] 998 | }, 999 | { 1000 | "cell_type": "markdown", 1001 | "source": [ 1002 | "Опа, мы вызвали значение от несуществующего ключа и вдруг ничего не выдало ошибку. Как же так? Давайте разбираться:\n", 1003 | "\n", 1004 | "* defaultdict(factory) - создай словарь вот с такой функцией по дефолту\n", 1005 | "\n", 1006 | "В данном случае мы вызвали int, который при вызове сам по себе дает 0:" 1007 | ], 1008 | "metadata": { 1009 | "id": "UxRdapueKyDt" 1010 | } 1011 | }, 1012 | { 1013 | "cell_type": "code", 1014 | "source": [ 1015 | "int()" 1016 | ], 1017 | "metadata": { 1018 | "colab": { 1019 | "base_uri": "https://localhost:8080/" 1020 | }, 1021 | "id": "ntaccAySLNip", 1022 | "outputId": "2be9ee33-0d10-4839-951f-55feeddbfdf7" 1023 | }, 1024 | "execution_count": null, 1025 | "outputs": [ 1026 | { 1027 | "output_type": "execute_result", 1028 | "data": { 1029 | "text/plain": [ 1030 | "0" 1031 | ] 1032 | }, 1033 | "metadata": {}, 1034 | "execution_count": 3 1035 | } 1036 | ] 1037 | }, 1038 | { 1039 | "cell_type": "markdown", 1040 | "source": [ 1041 | "Можно использовать несколько других вариантов, например, string, list, или в целом любую функцию (когда будем говорить про функции мы ощутим полную мощь данного инструмента)\n", 1042 | "\n", 1043 | "Давайте еще вот такой пример:" 1044 | ], 1045 | "metadata": { 1046 | "id": "-HfqQWcVLOuE" 1047 | } 1048 | }, 1049 | { 1050 | "cell_type": "code", 1051 | "source": [ 1052 | "s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]\n", 1053 | "d = defaultdict(list)\n", 1054 | "for k, v in s:\n", 1055 | " d[k].append(v)\n", 1056 | "\n", 1057 | "d.items()" 1058 | ], 1059 | "metadata": { 1060 | "colab": { 1061 | "base_uri": "https://localhost:8080/" 1062 | }, 1063 | "id": "vJcHybYrLaCz", 1064 | "outputId": "1c2c7914-e995-4730-dfd3-cb9ceeefcf71" 1065 | }, 1066 | "execution_count": null, 1067 | "outputs": [ 1068 | { 1069 | "output_type": "execute_result", 1070 | "data": { 1071 | "text/plain": [ 1072 | "dict_items([('yellow', [1, 3]), ('blue', [2, 4]), ('red', [1])])" 1073 | ] 1074 | }, 1075 | "metadata": {}, 1076 | "execution_count": 4 1077 | } 1078 | ] 1079 | }, 1080 | { 1081 | "cell_type": "markdown", 1082 | "source": [ 1083 | "Что здесь случилось? Мы задали в качестве изначальной функции list(). Что это значит? По дефолту создается пустой лист, внутри которого мы далее делаем append, то есть таким образом собираем все значения" 1084 | ], 1085 | "metadata": { 1086 | "id": "3gaw1khnLiKL" 1087 | } 1088 | }, 1089 | { 1090 | "cell_type": "markdown", 1091 | "source": [ 1092 | "## Животное дня" 1093 | ], 1094 | "metadata": { 1095 | "id": "bRBavKLsJbw-" 1096 | } 1097 | }, 1098 | { 1099 | "cell_type": "markdown", 1100 | "source": [ 1101 | "![](https://animaljournal.ru/articles/wild/primati/koshachiy_lemur/detenish_lemura1.jpg)" 1102 | ], 1103 | "metadata": { 1104 | "id": "Po6ms7FNJ3v4" 1105 | } 1106 | }, 1107 | { 1108 | "cell_type": "markdown", 1109 | "source": [ 1110 | "Это кошачий лемур. Их все так или иначе видели (по крайней мере вот в таком виде):" 1111 | ], 1112 | "metadata": { 1113 | "id": "kk6rs4ERJ5YS" 1114 | } 1115 | }, 1116 | { 1117 | "cell_type": "markdown", 1118 | "source": [ 1119 | "![](https://www.meme-arsenal.com/memes/819abc6f23381d803a640e91092ea4a1.jpg)" 1120 | ], 1121 | "metadata": { 1122 | "id": "OSsmBDTgKEce" 1123 | } 1124 | }, 1125 | { 1126 | "cell_type": "markdown", 1127 | "source": [ 1128 | "На Мадагаскаре (где они и обитают) их зовут маки! По размерам как кошка (действительно), при этом хвост может весить примерно половину от всего веса лемура, и это неудивительно - хвост лемура играют важную роль в его жизни.\n", 1129 | "\n", 1130 | "Помимо самых понятных прикладных функций (с помощью хвоста лемуры удерживают равновесие, будучи на ветках, а также балансируют с его помощью при прыжке), хвост также выполняет социальные функции\n", 1131 | "\n", 1132 | "С его помощью он более заметен своим сородичам, а также показывают, кто здесь главный (через секрет, которым они этот самый хвост обмазывают)\n", 1133 | "\n", 1134 | "А еще посмотрите, как они сидят)" 1135 | ], 1136 | "metadata": { 1137 | "id": "GLj3Arp-KMQr" 1138 | } 1139 | }, 1140 | { 1141 | "cell_type": "markdown", 1142 | "source": [ 1143 | "![](https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Ring.tailed.lemur.situp.arp.jpg/1024px-Ring.tailed.lemur.situp.arp.jpg)" 1144 | ], 1145 | "metadata": { 1146 | "id": "2yPxHCkDLaEC" 1147 | } 1148 | }, 1149 | { 1150 | "cell_type": "markdown", 1151 | "source": [ 1152 | "Лемуры - социальные животные, живут группой по 30 особей (причем у них матриархат), причем у них максимально яркая социальность: будучи одни, они просто с ума сходят, поэтому нормально изучить их когнитивные способности достаточно сложно" 1153 | ], 1154 | "metadata": { 1155 | "id": "Kh7Sr2VHLptu" 1156 | } 1157 | } 1158 | ] 1159 | } -------------------------------------------------------------------------------- /Lecture_5.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [] 7 | }, 8 | "kernelspec": { 9 | "name": "python3", 10 | "display_name": "Python 3" 11 | }, 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "# Python-1, Лекция 5\n", 21 | "\n", 22 | "Лектор: Петров Тимур" 23 | ], 24 | "metadata": { 25 | "id": "gul1ajImwD0W" 26 | } 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "source": [ 31 | "## Генераторы и итераторы" 32 | ], 33 | "metadata": { 34 | "id": "kVC6gn4agVTR" 35 | } 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "source": [ 40 | "Начнем с базы. Внутри Python есть две вещи: iterator и iterable. В чем разница и что это такое?\n", 41 | "\n", 42 | "Iterable - это объект, над которым можно проводить итерацию. Что такое итерация? По сути это процесс перебора элементов (например, строки/множества/списки - это итерируемые объекты)\n", 43 | "\n", 44 | "А что же тогда такое итератор? А это у нас объект, который занимается процессом итерации. По определению это класс, у которого реализованы методы next и iter (для iterable объекта реализуется только сам iter)\n" 45 | ], 46 | "metadata": { 47 | "id": "4KkW_VMkgaQf" 48 | } 49 | }, 50 | { 51 | "cell_type": "code", 52 | "source": [ 53 | "c = [1, 2, 3, 4]\n", 54 | "for i in c: # что здесь происходит? Неявно вызывается iter(c)\n", 55 | "# Причем iter() работает только для так называемых контейнеров (для всех, у кого есть __getitem__)\n", 56 | " print(i)" 57 | ], 58 | "metadata": { 59 | "colab": { 60 | "base_uri": "https://localhost:8080/" 61 | }, 62 | "id": "CX6_-IaCiAsZ", 63 | "outputId": "aa57b1fa-a08a-4380-98bd-3aff95093cda" 64 | }, 65 | "execution_count": null, 66 | "outputs": [ 67 | { 68 | "output_type": "stream", 69 | "name": "stdout", 70 | "text": [ 71 | "1\n", 72 | "2\n", 73 | "3\n", 74 | "4\n" 75 | ] 76 | } 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "source": [ 82 | "iter(c)" 83 | ], 84 | "metadata": { 85 | "colab": { 86 | "base_uri": "https://localhost:8080/" 87 | }, 88 | "id": "8T6mX3KmxP_l", 89 | "outputId": "69dc999a-2c39-4520-dbc9-1edf7e85fae5" 90 | }, 91 | "execution_count": null, 92 | "outputs": [ 93 | { 94 | "output_type": "execute_result", 95 | "data": { 96 | "text/plain": [ 97 | "" 98 | ] 99 | }, 100 | "metadata": {}, 101 | "execution_count": 8 102 | } 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "source": [ 108 | "for c in 32: #поэтому по числам не получится, они не итерируемые\n", 109 | " print(c)" 110 | ], 111 | "metadata": { 112 | "colab": { 113 | "base_uri": "https://localhost:8080/", 114 | "height": 194 115 | }, 116 | "id": "WWTdV5i4jjeW", 117 | "outputId": "dd3fde37-ff76-49b9-878b-ea931ca1e909" 118 | }, 119 | "execution_count": null, 120 | "outputs": [ 121 | { 122 | "output_type": "error", 123 | "ename": "TypeError", 124 | "evalue": "ignored", 125 | "traceback": [ 126 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 127 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 128 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;36m32\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 129 | "\u001b[0;31mTypeError\u001b[0m: 'int' object is not iterable" 130 | ] 131 | } 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "source": [ 137 | "n = iter(c)\n", 138 | "print(next(n))\n", 139 | "print(next(n))\n", 140 | "print(next(n))\n", 141 | "print(next(n))\n", 142 | "print(next(n))" 143 | ], 144 | "metadata": { 145 | "colab": { 146 | "base_uri": "https://localhost:8080/", 147 | "height": 288 148 | }, 149 | "id": "OEfcnk-Dxqae", 150 | "outputId": "c6e05c08-6db3-444f-b055-e9de0217693a" 151 | }, 152 | "execution_count": null, 153 | "outputs": [ 154 | { 155 | "output_type": "stream", 156 | "name": "stdout", 157 | "text": [ 158 | "1\n", 159 | "2\n", 160 | "3\n", 161 | "4\n" 162 | ] 163 | }, 164 | { 165 | "output_type": "error", 166 | "ename": "StopIteration", 167 | "evalue": "ignored", 168 | "traceback": [ 169 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 170 | "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", 171 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 172 | "\u001b[0;31mStopIteration\u001b[0m: " 173 | ] 174 | } 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "source": [ 180 | "l = [1, 2, 3]\n", 181 | "next(l) #список iterable, но не итератор" 182 | ], 183 | "metadata": { 184 | "colab": { 185 | "base_uri": "https://localhost:8080/", 186 | "height": 204 187 | }, 188 | "id": "hhzoGeFtMC-Z", 189 | "outputId": "c82b6386-9215-4ca4-b33b-bc46a25632c8" 190 | }, 191 | "execution_count": 5, 192 | "outputs": [ 193 | { 194 | "output_type": "error", 195 | "ename": "TypeError", 196 | "evalue": "ignored", 197 | "traceback": [ 198 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 199 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 200 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ml\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ml\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 201 | "\u001b[0;31mTypeError\u001b[0m: 'list' object is not an iterator" 202 | ] 203 | } 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "source": [ 209 | "Где можно встретить итераторы? Да на самом деле много где!\n", 210 | "\n", 211 | "Например, функция zip возвращает итератор:" 212 | ], 213 | "metadata": { 214 | "id": "OT7BVsDuMc3N" 215 | } 216 | }, 217 | { 218 | "cell_type": "code", 219 | "source": [ 220 | "a = [1, 2, 3]\n", 221 | "b = [1, 2, 3]\n", 222 | "c = zip(a, b)\n", 223 | "print(next(c))\n", 224 | "print(next(c))\n", 225 | "print(next(c))" 226 | ], 227 | "metadata": { 228 | "colab": { 229 | "base_uri": "https://localhost:8080/" 230 | }, 231 | "id": "oQniCjrDMhW3", 232 | "outputId": "568ba44d-1d61-401b-a049-a034d515e830" 233 | }, 234 | "execution_count": 8, 235 | "outputs": [ 236 | { 237 | "output_type": "stream", 238 | "name": "stdout", 239 | "text": [ 240 | "(1, 1)\n", 241 | "(2, 2)\n", 242 | "(3, 3)\n" 243 | ] 244 | } 245 | ] 246 | }, 247 | { 248 | "cell_type": "markdown", 249 | "source": [ 250 | "А также есть функция enumerate() - она делает нумерацию элементов, что можно впоследствие использовать внутри for:" 251 | ], 252 | "metadata": { 253 | "id": "QtmMtONGMptv" 254 | } 255 | }, 256 | { 257 | "cell_type": "code", 258 | "source": [ 259 | "k = [4, 5, 6]\n", 260 | "k_e = enumerate(k)\n", 261 | "print(next(k_e))\n", 262 | "print(next(k_e))\n", 263 | "print(next(k_e))" 264 | ], 265 | "metadata": { 266 | "colab": { 267 | "base_uri": "https://localhost:8080/" 268 | }, 269 | "id": "ya81LwQ4MkvD", 270 | "outputId": "3137b4ef-8f30-4362-e402-79da76d06a36" 271 | }, 272 | "execution_count": 9, 273 | "outputs": [ 274 | { 275 | "output_type": "stream", 276 | "name": "stdout", 277 | "text": [ 278 | "(0, 4)\n", 279 | "(1, 5)\n", 280 | "(2, 6)\n" 281 | ] 282 | } 283 | ] 284 | }, 285 | { 286 | "cell_type": "code", 287 | "source": [ 288 | "for num, el in enumerate(k):\n", 289 | " print(num, el)" 290 | ], 291 | "metadata": { 292 | "colab": { 293 | "base_uri": "https://localhost:8080/" 294 | }, 295 | "id": "eKc3NA8YM7tQ", 296 | "outputId": "920adc5e-cd03-4bc9-d6ef-57958b4633e0" 297 | }, 298 | "execution_count": 10, 299 | "outputs": [ 300 | { 301 | "output_type": "stream", 302 | "name": "stdout", 303 | "text": [ 304 | "0 4\n", 305 | "1 5\n", 306 | "2 6\n" 307 | ] 308 | } 309 | ] 310 | }, 311 | { 312 | "cell_type": "markdown", 313 | "source": [ 314 | "## Генераторы" 315 | ], 316 | "metadata": { 317 | "id": "3EC2WocBnk6b" 318 | } 319 | }, 320 | { 321 | "cell_type": "markdown", 322 | "source": [ 323 | "Гораздо интереснее посмотреть на генераторы. По сути, такой же итератор, так сказать, потому что любой генератор можно сделать с помощью итератора\n", 324 | "\n", 325 | "Как распознать генератор? Простым словом yield!" 326 | ], 327 | "metadata": { 328 | "id": "-Pu_cGgTnn1K" 329 | } 330 | }, 331 | { 332 | "cell_type": "code", 333 | "source": [ 334 | "def simple_gen():\n", 335 | " yield \"Какапо\"\n", 336 | " yield \"Кеа\"\n", 337 | " yield \"Ара\"\n", 338 | " yield \"Какаду\"\n", 339 | " yield \"Корелла\"\n", 340 | "\n", 341 | "s = simple_gen()\n", 342 | "print(next(s))\n", 343 | "print(next(s))\n", 344 | "print(next(s))\n", 345 | "print(next(s))\n", 346 | "print(next(s))\n", 347 | "print(next(s)) # опа, знакомая нам ошибка\n" 348 | ], 349 | "metadata": { 350 | "colab": { 351 | "base_uri": "https://localhost:8080/", 352 | "height": 307 353 | }, 354 | "id": "nBEn93pXoNtG", 355 | "outputId": "fd730d45-7e3f-4616-9afe-a14f92f5ee62" 356 | }, 357 | "execution_count": null, 358 | "outputs": [ 359 | { 360 | "output_type": "stream", 361 | "name": "stdout", 362 | "text": [ 363 | "Какапо\n", 364 | "Кеа\n", 365 | "Ара\n", 366 | "Какаду\n", 367 | "Корелла\n" 368 | ] 369 | }, 370 | { 371 | "output_type": "error", 372 | "ename": "StopIteration", 373 | "evalue": "ignored", 374 | "traceback": [ 375 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 376 | "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", 377 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 14\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# опа, знакомая нам ошибка\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 378 | "\u001b[0;31mStopIteration\u001b[0m: " 379 | ] 380 | } 381 | ] 382 | }, 383 | { 384 | "cell_type": "markdown", 385 | "source": [ 386 | "Как работает генератор, что за yield?\n", 387 | "\n", 388 | "Все просто:\n", 389 | "\n", 390 | "Мы вызываем функцию. Когда он доходит до yield, то выдает значение. После этого функция переходит как бы в режим ожидания. Когда мы ее вызываем в следующий раз, он начинает с места, где закончил и продолжает. Как закончить жизнь генератора? Сделать return" 391 | ], 392 | "metadata": { 393 | "id": "_USnaMOoorom" 394 | } 395 | }, 396 | { 397 | "cell_type": "code", 398 | "source": [ 399 | "def fibonacci(n):\n", 400 | " a, b, counter = 0, 1, 0\n", 401 | " while True:\n", 402 | " if (counter > n):\n", 403 | " return\n", 404 | " yield a\n", 405 | " a, b = b, a + b\n", 406 | " counter += 1\n", 407 | "\n", 408 | "f = fibonacci(5)\n", 409 | "print(f)\n", 410 | "for x in f:\n", 411 | " print(x, end=\" \")" 412 | ], 413 | "metadata": { 414 | "colab": { 415 | "base_uri": "https://localhost:8080/" 416 | }, 417 | "id": "X2kUdOBDpRW9", 418 | "outputId": "dbe04b4a-32d3-478f-ea8b-81f22cb716f0" 419 | }, 420 | "execution_count": null, 421 | "outputs": [ 422 | { 423 | "output_type": "stream", 424 | "name": "stdout", 425 | "text": [ 426 | "\n", 427 | "0 1 1 2 3 5 " 428 | ] 429 | } 430 | ] 431 | }, 432 | { 433 | "cell_type": "markdown", 434 | "source": [ 435 | "Ну хорошо, в нашем первом примере как-то это явно неудобно, писать кучу строк... А можно, на самом деле, сделать вот такую штуку:" 436 | ], 437 | "metadata": { 438 | "id": "yUGJBP6zrNx2" 439 | } 440 | }, 441 | { 442 | "cell_type": "code", 443 | "source": [ 444 | "def simple_gen():\n", 445 | " yield from [\"Какапо\", \"Кеа\", \"Ара\", \"Какаду\", \"Корелла\"] #yield from работает только с iterable объектами\n", 446 | "\n", 447 | "s = simple_gen()\n", 448 | "print(next(s))\n", 449 | "print(next(s))\n", 450 | "print(next(s))\n", 451 | "print(next(s))\n", 452 | "print(next(s))" 453 | ], 454 | "metadata": { 455 | "colab": { 456 | "base_uri": "https://localhost:8080/" 457 | }, 458 | "id": "A1JTCWnSsB4E", 459 | "outputId": "8cc7791a-9f00-4c94-c162-19298f0b1cca" 460 | }, 461 | "execution_count": null, 462 | "outputs": [ 463 | { 464 | "output_type": "stream", 465 | "name": "stdout", 466 | "text": [ 467 | "Какапо\n", 468 | "Кеа\n", 469 | "Ара\n", 470 | "Какаду\n", 471 | "Корелла\n" 472 | ] 473 | } 474 | ] 475 | }, 476 | { 477 | "cell_type": "markdown", 478 | "source": [ 479 | "Что еще крутого есть в генераторах? Для итераторов мы можем только ходить по значениям и делать с ними что-то (итерироваться). А вот в генераторы мы можем отправлять значения!\n", 480 | "\n", 481 | "В чем прикол: на самом деле yield не только дает значения, но и послыает значения. Если воспринимать генератор как итератор, то разницы никакой, в общем-то, а вот если расширять функции генератора, то не совсем.\n", 482 | "\n", 483 | "По дефолту yield выдает None, а поскольку мы ничего с этим не делаем, то как бы и ок. Но мы можем отправить что-то с помощью send(), и таким образом, модернизировать значения!" 484 | ], 485 | "metadata": { 486 | "id": "Y8GMBkd7soKV" 487 | } 488 | }, 489 | { 490 | "cell_type": "code", 491 | "source": [ 492 | "def count(firstval=0, step=1):\n", 493 | " counter = firstval\n", 494 | " while True:\n", 495 | " new_counter_val = yield counter # здесь возвращается либо None, либо результат send\n", 496 | " if new_counter_val is None:\n", 497 | " counter += step\n", 498 | " else:\n", 499 | " counter = new_counter_val[0]\n", 500 | " step = new_counter_val[1]\n", 501 | "\n", 502 | "start_value = 2.1\n", 503 | "step_value = 0.3\n", 504 | "counter = count(start_value, step_value)\n", 505 | "for i in range(10):\n", 506 | " new_value = next(counter)\n", 507 | " print(f\"{new_value:2.2f}\", end=\", \")\n", 508 | "\n", 509 | "print()\n", 510 | "print(\"set current count value to another value:\")\n", 511 | "counter.send((100.5, 2)) # ооотправляем посылочку\n", 512 | "for i in range(10):\n", 513 | " new_value = next(counter)\n", 514 | " print(f\"{new_value:2.2f}\", end=\", \")" 515 | ], 516 | "metadata": { 517 | "colab": { 518 | "base_uri": "https://localhost:8080/" 519 | }, 520 | "id": "3pU2RizrsT5B", 521 | "outputId": "bab751cf-1673-4bb3-b732-70a62c4fad71" 522 | }, 523 | "execution_count": null, 524 | "outputs": [ 525 | { 526 | "output_type": "stream", 527 | "name": "stdout", 528 | "text": [ 529 | "2.10, 2.40, 2.70, 3.00, 3.30, 3.60, 3.90, 4.20, 4.50, 4.80, \n", 530 | "set current count value to another value:\n", 531 | "102.50, 104.50, 106.50, 108.50, 110.50, 112.50, 114.50, 116.50, 118.50, 120.50, " 532 | ] 533 | } 534 | ] 535 | }, 536 | { 537 | "cell_type": "markdown", 538 | "source": [ 539 | "А еще можем вкидывать ошибки)))" 540 | ], 541 | "metadata": { 542 | "id": "yLCNxcgQuzVK" 543 | } 544 | }, 545 | { 546 | "cell_type": "code", 547 | "source": [ 548 | "def count(firstval=0, step=1):\n", 549 | " counter = firstval\n", 550 | " while True:\n", 551 | " try:\n", 552 | " new_counter_val = yield counter\n", 553 | " if new_counter_val is None:\n", 554 | " counter += step\n", 555 | " else:\n", 556 | " counter = new_counter_val\n", 557 | " except Exception:\n", 558 | " yield (firstval, step, counter)\n", 559 | "\n", 560 | "c = count()\n", 561 | "for i in range(6):\n", 562 | " print(next(c))\n", 563 | "print(\"Our state\")\n", 564 | "state_of_count = c.throw(Exception)\n", 565 | "print(state_of_count)\n", 566 | "for i in range(3):\n", 567 | " print(next(c))" 568 | ], 569 | "metadata": { 570 | "colab": { 571 | "base_uri": "https://localhost:8080/" 572 | }, 573 | "id": "NvmQDH_Uu3Ad", 574 | "outputId": "d1b308eb-216d-47a3-f668-e1a6b2b681d4" 575 | }, 576 | "execution_count": null, 577 | "outputs": [ 578 | { 579 | "output_type": "stream", 580 | "name": "stdout", 581 | "text": [ 582 | "0\n", 583 | "1\n", 584 | "2\n", 585 | "3\n", 586 | "4\n", 587 | "5\n", 588 | "Our state\n", 589 | "(0, 1, 5)\n", 590 | "5\n", 591 | "6\n", 592 | "7\n" 593 | ] 594 | } 595 | ] 596 | }, 597 | { 598 | "cell_type": "markdown", 599 | "source": [ 600 | "И на всякий случай, с чего начали, к тому и пришли: генераторы тоже можно передавать в качестве аргументов функции!" 601 | ], 602 | "metadata": { 603 | "id": "Dm9o_pBvvQMD" 604 | } 605 | }, 606 | { 607 | "cell_type": "code", 608 | "source": [ 609 | "def firstn(generator, n):\n", 610 | " g = generator()\n", 611 | " for i in range(n):\n", 612 | " yield next(g)\n", 613 | "\n", 614 | "print(list(firstn(simple_gen, 3)))" 615 | ], 616 | "metadata": { 617 | "colab": { 618 | "base_uri": "https://localhost:8080/" 619 | }, 620 | "id": "W5d1pWdFvXxX", 621 | "outputId": "bb8ac7b4-d838-48e3-dab2-fbb41d609e9a" 622 | }, 623 | "execution_count": null, 624 | "outputs": [ 625 | { 626 | "output_type": "stream", 627 | "name": "stdout", 628 | "text": [ 629 | "['Какапо', 'Кеа', 'Ара']\n" 630 | ] 631 | } 632 | ] 633 | }, 634 | { 635 | "cell_type": "markdown", 636 | "source": [ 637 | "А зачем нам в целом нужны генераторы и итераторы? На самом деле причина одна (но очень важная) - экономия памяти. Генератор и итератор хранят только 1 значение во времени (ей не треубется хранить все, что есть)\n", 638 | "\n", 639 | "Давайте на примере:" 640 | ], 641 | "metadata": { 642 | "id": "kld3ajmVPpLP" 643 | } 644 | }, 645 | { 646 | "cell_type": "code", 647 | "source": [ 648 | "import sys\n", 649 | "nums_squared_lc = [i * 2 for i in range(10000)]\n", 650 | "sys.getsizeof(nums_squared_lc) ##выдает сколько памяти в байтах занимает" 651 | ], 652 | "metadata": { 653 | "colab": { 654 | "base_uri": "https://localhost:8080/" 655 | }, 656 | "id": "Q05RrBtDP8CV", 657 | "outputId": "fa7e8963-f6fc-4f4b-e081-fdf5ec431f49" 658 | }, 659 | "execution_count": 11, 660 | "outputs": [ 661 | { 662 | "output_type": "execute_result", 663 | "data": { 664 | "text/plain": [ 665 | "85176" 666 | ] 667 | }, 668 | "metadata": {}, 669 | "execution_count": 11 670 | } 671 | ] 672 | }, 673 | { 674 | "cell_type": "code", 675 | "source": [ 676 | "nums_squared_gc = (i ** 2 for i in range(10000)) # по существу это все генератор...\n", 677 | "print(sys.getsizeof(nums_squared_gc))" 678 | ], 679 | "metadata": { 680 | "colab": { 681 | "base_uri": "https://localhost:8080/" 682 | }, 683 | "id": "s8hXv90oP8xJ", 684 | "outputId": "abd96e6f-0626-4ddc-c9e3-30d30dd0fd41" 685 | }, 686 | "execution_count": 12, 687 | "outputs": [ 688 | { 689 | "output_type": "stream", 690 | "name": "stdout", 691 | "text": [ 692 | "104\n" 693 | ] 694 | } 695 | ] 696 | }, 697 | { 698 | "cell_type": "markdown", 699 | "source": [ 700 | "## Попугай дня" 701 | ], 702 | "metadata": { 703 | "id": "xAL_LbetgNuo" 704 | } 705 | }, 706 | { 707 | "cell_type": "markdown", 708 | "source": [ 709 | "![](https://i.pinimg.com/originals/2d/59/dc/2d59dc37ef7d2c3767f075e05ed193a6.jpg)" 710 | ], 711 | "metadata": { 712 | "id": "QdCs2NJKgRGf" 713 | } 714 | }, 715 | { 716 | "cell_type": "markdown", 717 | "source": [ 718 | "А это не попугай! Это капибара (или ее еще называют водосвинкой, а в Мексике ее вообще зовут кокосовой собачкой)\n", 719 | "\n", 720 | "Самые крупные грызуны на планете, максимально милейшие, дружелюбные и очень хорошо ладят с людьми. Едят траву, а водосвинками называются, потому что они плавают и в целом любят воду\n", 721 | "\n", 722 | "Какие факты есть про них:\n", 723 | "\n", 724 | "1. Они балдежные и очень спокойные\n", 725 | "\n", 726 | "2. Католическая церковь в XVI веке говорила, что капибары из-за их полуводного образа жизни являются рыбами, а поэтому их можно было есть в пост\n", 727 | "\n", 728 | "3. В Аргентине недавно переселились в богатые районы Буэнос-Айреса (где, естественно, много зелени) и теперь там хозяйствуют (поэтому есть кучами мемов с капибарами-коммунистами). А поскольку естественные враги капибар - это кайманы и пумы, то как-то их и не выселишь" 729 | ], 730 | "metadata": { 731 | "id": "2fjnj9aegYse" 732 | } 733 | }, 734 | { 735 | "cell_type": "markdown", 736 | "source": [ 737 | "![](https://i.pinimg.com/originals/83/0e/16/830e163003a346352ac0d9ba20203b2e.jpg)" 738 | ], 739 | "metadata": { 740 | "id": "X7eLvbODhmUG" 741 | } 742 | } 743 | ] 744 | } -------------------------------------------------------------------------------- /Lecture_9.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "collapsed_sections": [ 8 | "-2k_UncjnhHQ", 9 | "c11qThyDs5tj", 10 | "g5mUKTcO5Cv2", 11 | "XQyJ09DF9DEN", 12 | "qrLg4waSKBCh", 13 | "gMFY_bf533vm" 14 | ] 15 | }, 16 | "kernelspec": { 17 | "name": "python3", 18 | "display_name": "Python 3" 19 | }, 20 | "language_info": { 21 | "name": "python" 22 | } 23 | }, 24 | "cells": [ 25 | { 26 | "cell_type": "markdown", 27 | "source": [ 28 | "# Python-1, лекция 9\n", 29 | "\n", 30 | "Лектор: Петров Тимур" 31 | ], 32 | "metadata": { 33 | "id": "hprOLVzS5nOp" 34 | } 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "source": [ 39 | "# Регулярные выражения" 40 | ], 41 | "metadata": { 42 | "id": "xSQAp0rw6-Qr" 43 | } 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": { 48 | "id": "NZiBXLMElWND" 49 | }, 50 | "source": [ 51 | "## Что такое регулярные выражения?\n", 52 | "\n", 53 | "Регулярное выражение - это строка, которая задает некоторый паттерн (шаблон) для поиска внутри строки. С его помощью можно находить в тексте необходимые части (например, все города внутри текста, слова на русском и так далее), а также проверять строки на правильность (например, проверка e-mail, телефона и тому подобное)\n", 54 | "\n", 55 | "Это очень удобная и сильная вещь, но палка о двух концах (об этом будет далее). Итак, приступим:" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": { 61 | "id": "IK83DxlUmx83" 62 | }, 63 | "source": [ 64 | "## Где потренироваться и проверять регулярку\n", 65 | "\n", 66 | "Ответ очевиден - в Питоне с помощью библиотеки re 🐍\n", 67 | "\n", 68 | "[Ссылка на документацию](https://docs.python.org/3/library/re.html) (осторожно, english)\n", 69 | "\n", 70 | "Но если лень писать код, или хочется видеть результат в режиме онлайн, то существует множество сайтов, где можно это посмотреть, например, [вот здесь](https://https://regex101.com/) (не забудьте слева выбрать Flavor Python, потому что реализация различается, хоть и не сильно)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": { 76 | "id": "-2k_UncjnhHQ" 77 | }, 78 | "source": [ 79 | "## Основы и квантификаторы" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "source": [ 85 | "Допустим, вам нужно найти просто все вхождения слова внутри текста. Тогда регулярное выражение не будет иметь в себе никаких сложностей и будет состоять из самого слова:" 86 | ], 87 | "metadata": { 88 | "id": "jYQTZCgj6Ke3" 89 | } 90 | }, 91 | { 92 | "cell_type": "code", 93 | "metadata": { 94 | "colab": { 95 | "base_uri": "https://localhost:8080/" 96 | }, 97 | "id": "r1O9hf6OlQOT", 98 | "outputId": "2c6a3869-222f-4bfe-c803-e984788310c6" 99 | }, 100 | "source": [ 101 | "import re # библиотека для регулярок в Питоне\n", 102 | "\n", 103 | "# re.search(pattern, text) - поиск первого паттерна вида pattern внутри строки text.\n", 104 | "\n", 105 | "match = re.search(r'ah', r'ahahah aha') # r перед строкой - считываем строку как есть (raw)\n", 106 | "print(match)\n", 107 | "print(match.group(0))\n", 108 | "\n", 109 | "# re.findall(pattern, text) - поиск всех паттернов вида pattern внутри строки text. Возвращает список всех совпадений\n", 110 | "\n", 111 | "match = re.findall(r'aha', r'ahahah aha') # r перед строкой - считываем строку как есть (raw)\n", 112 | "print(match)\n", 113 | "\n", 114 | "# re.compile(pattern, flags) - запись паттерна, который можно использовать в дальнейшем. Flags дает дополнительные фичи\n", 115 | "\n", 116 | "pattern = re.compile(r'aha', flags = re.A)\n", 117 | "print(pattern)\n", 118 | "match = re.findall(pattern, r'ahahah aha')\n", 119 | "print(match)" 120 | ], 121 | "execution_count": null, 122 | "outputs": [ 123 | { 124 | "output_type": "stream", 125 | "name": "stdout", 126 | "text": [ 127 | "\n", 128 | "ah\n", 129 | "['aha', 'aha']\n", 130 | "re.compile('aha', re.ASCII)\n", 131 | "['aha', 'aha']\n" 132 | ] 133 | } 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": { 139 | "id": "nba8w_oPqrLw" 140 | }, 141 | "source": [ 142 | "Усложним задачу. Допустим, что мы ищем слово цвет на английском, которое может записываться как color (Ам), так и colour (Бр)\n", 143 | "\n", 144 | "Для этого есть квантификаторы, которые могут учитывать, сколько раз может встречаться та или иная буква:\n", 145 | "\n", 146 | "* {a} - встречается ровно a раз\n", 147 | "* {a,b} - встречается от a до b раз\n", 148 | "* {,b} - максимум b раз\n", 149 | "* {a,} - минимум a раз\n", 150 | "\n", 151 | "Квантификатор будет ставится после буквы (или простого шаблона), для которого он нужен.\n", 152 | "\n", 153 | "В нашем случае это будет выглядеть так:\n", 154 | "\n" 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "metadata": { 160 | "colab": { 161 | "base_uri": "https://localhost:8080/" 162 | }, 163 | "id": "TLPeBBLTrcyY", 164 | "outputId": "2b0855fc-ffd0-489e-9624-48ed24aa0851" 165 | }, 166 | "source": [ 167 | "pattern = re.compile(r'colou{,1}r') # color, colour - будет засчитано\n", 168 | "s = 'color, colour'\n", 169 | "match = re.findall(pattern, s)\n", 170 | "print(match)" 171 | ], 172 | "execution_count": null, 173 | "outputs": [ 174 | { 175 | "output_type": "stream", 176 | "name": "stdout", 177 | "text": [ 178 | "['color', 'colour']\n" 179 | ] 180 | } 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": { 186 | "id": "1fKP3cBFsI-m" 187 | }, 188 | "source": [ 189 | "Некоторые квантификаторы используется достаточно часто, поэтому для них есть особенные символы:\n", 190 | "\n", 191 | "* $?$ = {0,1} - встречается 0 или 1 раз\n", 192 | "* $*$ = {0,} - встречается от 0 раз и больше\n", 193 | "* $+$ = {1,} - встречается от 1 раза и больше\n", 194 | "\n", 195 | "Можем упростить наше выражение:" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "metadata": { 201 | "colab": { 202 | "base_uri": "https://localhost:8080/" 203 | }, 204 | "id": "WjuB9ryNsoYP", 205 | "outputId": "e3bd799b-5d0f-420b-9a73-1ce85102d1d0" 206 | }, 207 | "source": [ 208 | "pattern = re.compile(r'c?o?l?o?u?r')\n", 209 | "s = 'color, colour, olur'\n", 210 | "match = re.findall(pattern, s)\n", 211 | "print(match)\n", 212 | "\n", 213 | "pattern = re.compile(r'colou*r')\n", 214 | "s = 'color, colour colouuuuuuuuuuuuuuuuuur'\n", 215 | "match = re.findall(pattern, s)\n", 216 | "print(match)\n", 217 | "\n", 218 | "pattern = re.compile(r'colo.*r')\n", 219 | "s = 'color, colour colouuuuuuuuuuuuuuuuuur'\n", 220 | "match = re.findall(pattern, s)\n", 221 | "print(match)" 222 | ], 223 | "execution_count": null, 224 | "outputs": [ 225 | { 226 | "output_type": "stream", 227 | "name": "stdout", 228 | "text": [ 229 | "['color', 'colour', 'olur']\n", 230 | "['color', 'colour', 'colouuuuuuuuuuuuuuuuuur']\n", 231 | "['color, colour colouuuuuuuuuuuuuuuuuur']\n" 232 | ] 233 | } 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": { 239 | "id": "c11qThyDs5tj" 240 | }, 241 | "source": [ 242 | "## Особые символы" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "source": [ 248 | "Для того, чтобы сделать поиск уникальным, нам теперь надо добавить дополнительные символы, с помощью которых можно осуществлять поиск. Среди таких:\n", 249 | "\n", 250 | "* $.$ - любой символ, кроме начала строки\n", 251 | "* $[]$ - набор символов (символы можно перечислять через -, например [A-Z] = все заглавные символы английского алфавита)\n", 252 | "* [^] - отрицание набора символов (то есть [^A-Z] = все, кроме заглавных букв английского алфавита)\n", 253 | "* ^ - начало текста\n", 254 | "* $ - конец текста\n", 255 | "\n", 256 | "Отдельные символы для букв, цифр и символов:\n", 257 | "\n", 258 | "* \\d - цифра\n", 259 | "* \\D - все, кроме цифры\n", 260 | "* \\w - любая буква, цифра, а также нижнее подчеркивание (буква - это все, что считается буквой в Unicode, то есть и русские буквы, и так далее)\n", 261 | "* \\W - все, кроме букв, цифр и нижнего подчеркивания\n", 262 | "* \\s - пробельные символы (пробел, табуляция, перенос строки и так далее)\n", 263 | "* \\S - все, кроме пробельного символа\n", 264 | "* \\b - начало слова (слева \\W, справа \\w) - ставится по позиции, а не по символу\n", 265 | "* \\B - не начало слова\n", 266 | "\n", 267 | "И есть еще один отдельный символ: \\ - символ экранирования. Экранирование дает прочесть символ как символ, а не как шаблон (например, точку). Внутри набора экранируют только символы ] и \\\\.\n" 268 | ], 269 | "metadata": { 270 | "id": "_uf6kR6J6HSb" 271 | } 272 | }, 273 | { 274 | "cell_type": "code", 275 | "metadata": { 276 | "colab": { 277 | "base_uri": "https://localhost:8080/" 278 | }, 279 | "id": "dNMcq7nZxdmK", 280 | "outputId": "650a1274-c71d-4927-8539-6ebe3f62855f" 281 | }, 282 | "source": [ 283 | "# Хотим найти все слова на английском\n", 284 | "\n", 285 | "pattern = re.compile(r'[a-zA-Z]+')\n", 286 | "s = 'color, colour, sfasdas, lfosdlf5lsfl..'\n", 287 | "match = re.findall(pattern, s)\n", 288 | "print(match)\n", 289 | "\n", 290 | "# Хотим найти даты вида дд.мм.гггг\n", 291 | "\n", 292 | "pattern = re.compile(r'\\d{2}\\.\\d{2}\\.\\d{4}')\n", 293 | "s = 'color, colour, sfasdas, lfosdlf5lsfl 19.04.2012'\n", 294 | "match = re.findall(pattern, s)\n", 295 | "print(match)\n", 296 | "\n", 297 | "# Хотим найти все слова на английском, перед которыми нет ничего\n", 298 | "\n", 299 | "pattern = re.compile(r'\\b[a-zA-Z]+')\n", 300 | "s = 'color, colour, 4sfasdas, lfosdlf5lsfl'\n", 301 | "match = re.findall(pattern, s)\n", 302 | "print(match)" 303 | ], 304 | "execution_count": null, 305 | "outputs": [ 306 | { 307 | "output_type": "stream", 308 | "name": "stdout", 309 | "text": [ 310 | "['color', 'colour', 'sfasdas', 'lfosdlf', 'lsfl']\n", 311 | "['19.04.2012']\n", 312 | "['color', 'colour', 'lfosdlf']\n" 313 | ] 314 | } 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": { 320 | "id": "DebQA-MszGjD" 321 | }, 322 | "source": [ 323 | "## Группировки" 324 | ] 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "source": [ 329 | "Допустим, что наш шаблон нужно повторить несколько раз. Например, нам нужно найти MAC-адрес в тексте (MAC-адрес - это физический адрес устройства в Интернете). Он представляет из себя 6 групп из чисел в шестнадцатеричной системе, которая разделена - или : (пример: 01-23-45-67-89-ab)\n", 330 | "\n", 331 | "Если писать, как есть, то это будет выглядеть как:\n", 332 | "\n", 333 | "[0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}[:-][0-9a-fA-F]{2}\n", 334 | "\n", 335 | "Громоздко и некрасиво, читать сложно. Но здесь есть повторяющийся паттерн [0-9a-fA-F]{2}[:-]\n", 336 | "\n", 337 | "Паттерны можно группировать с помощью скобок:\n", 338 | "\n", 339 | "* (?:) - внутри указывается паттерн\n", 340 | "\n", 341 | "К ней уже можно применять те же самые квантификаторы. И тогда у нас будет:" 342 | ], 343 | "metadata": { 344 | "id": "IXp3GtlW6RU8" 345 | } 346 | }, 347 | { 348 | "cell_type": "code", 349 | "metadata": { 350 | "colab": { 351 | "base_uri": "https://localhost:8080/" 352 | }, 353 | "id": "-P3leAtj0oQe", 354 | "outputId": "b5a450a9-2e7f-402c-b30e-8f9c3f4a8719" 355 | }, 356 | "source": [ 357 | "pattern = re.compile(r'[0-9a-fA-F]{2}(?:[:-][0-9a-fA-F]{2}){5}')\n", 358 | "s = 'color, colour, sfasdas, lfosdlf5lsfl 19.04.2012 01:89:14:16:a1:a2'\n", 359 | "match = re.findall(pattern, s)\n", 360 | "print(match)" 361 | ], 362 | "execution_count": null, 363 | "outputs": [ 364 | { 365 | "output_type": "stream", 366 | "name": "stdout", 367 | "text": [ 368 | "['01:89:14:16:a1:a2']\n" 369 | ] 370 | } 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "metadata": { 376 | "id": "nyWWInNv06nP" 377 | }, 378 | "source": [ 379 | "Кроме того, внутри группировки можно использовать перечисление (логическое OR). Делается это с помощью |\n", 380 | "\n", 381 | "Например, пусть часть адреса зашифрована с помощью комбинации xx. Тогда, чтобы найти адрес, надо сделать вот так:" 382 | ] 383 | }, 384 | { 385 | "cell_type": "code", 386 | "metadata": { 387 | "colab": { 388 | "base_uri": "https://localhost:8080/" 389 | }, 390 | "id": "K_6yJHch1PS2", 391 | "outputId": "a5e350e1-d0c2-4746-fdad-261b19b32fe2" 392 | }, 393 | "source": [ 394 | "pattern = re.compile(r'(?:[0-9a-fA-F]{2}|[Xx]{2})(?:[:-][0-9a-fA-F]{2}|[:-][Xx]{2}){5}')\n", 395 | "s = 'color, colour, sfasdas, lfosdlf5lsfl 19.04.2012 01:22:14:16:a1:a2 xx:-2:14:XX:a1:a2'\n", 396 | "match = re.findall(pattern, s)\n", 397 | "print(match)" 398 | ], 399 | "execution_count": null, 400 | "outputs": [ 401 | { 402 | "output_type": "stream", 403 | "name": "stdout", 404 | "text": [ 405 | "['01:12:14:16:a1:a2', 'xx:-2:14:XX:a1:a2']\n" 406 | ] 407 | } 408 | ] 409 | }, 410 | { 411 | "cell_type": "markdown", 412 | "metadata": { 413 | "id": "PED9_cke2qAW" 414 | }, 415 | "source": [ 416 | "Группировки могут также использоваться для различных проверок. Скажем, если нам нужно проверить, что перед нужным текстом находятся что-то нужное (например, ищем, когда у нас встречается II только перед именем Николай). Для этого есть так называемые условия lookaround:\n", 417 | "\n", 418 | "* (?=) - проверить, встречается ли этот паттерн после нужного паттерна\n", 419 | "* (?!) - проверить, не встречается ли этот паттерн после нужного паттерна\n", 420 | "* (?<=) - проверить, встречается ли этот паттерн до нужного паттерна (но только фиксированной длины паттерн)\n", 421 | "* (? rotate(1) -> 2-3-4-5-1\n", 730 | "print(d)\n", 731 | "d.rotate(-2) # вправо\n", 732 | "# 1-2-3-4-5 -> rotate(-2) -> 4-5-1-2-3\n", 733 | "print(d)\n", 734 | "d.reverse() # перевернуть очередь\n", 735 | "print(d)\n", 736 | "\n", 737 | "print('-' * 30)\n", 738 | "\n", 739 | "# вставка и удаление\n", 740 | "\n", 741 | "d.insert(1, 'x')\n", 742 | "print(d)\n", 743 | "print(d.index('x'))\n", 744 | "d.remove('x')\n", 745 | "print(d)" 746 | ], 747 | "execution_count": null, 748 | "outputs": [ 749 | { 750 | "output_type": "stream", 751 | "name": "stdout", 752 | "text": [ 753 | "deque(['ab', 'ab', 'bc', 'cd', 'ab'])\n", 754 | "------------------------------\n", 755 | "ab\n", 756 | "ab\n", 757 | "bc\n", 758 | "cd\n", 759 | "ab\n", 760 | "------------------------------\n", 761 | "deque(['pp', 'hh', 'dd', 'ab', 'ab', 'bc', 'cd', 'ab', 'aa', 'hh', 'pp'])\n", 762 | "------------------------------\n", 763 | "pp\n", 764 | "pp\n", 765 | "deque(['hh', 'dd', 'ab', 'ab', 'bc', 'cd', 'ab', 'aa', 'hh'])\n", 766 | "------------------------------\n", 767 | "hh\n", 768 | "aa\n", 769 | "2\n", 770 | "------------------------------\n", 771 | "deque(['hh', 'hh', 'dd', 'ab', 'ab', 'bc', 'cd', 'ab', 'aa'])\n", 772 | "deque(['dd', 'ab', 'ab', 'bc', 'cd', 'ab', 'aa', 'hh', 'hh'])\n", 773 | "deque(['hh', 'hh', 'aa', 'ab', 'cd', 'bc', 'ab', 'ab', 'dd'])\n", 774 | "------------------------------\n", 775 | "deque(['hh', 'x', 'hh', 'aa', 'ab', 'cd', 'bc', 'ab', 'ab', 'dd'])\n", 776 | "1\n", 777 | "deque(['hh', 'hh', 'aa', 'ab', 'cd', 'bc', 'ab', 'ab', 'dd'])\n" 778 | ] 779 | } 780 | ] 781 | }, 782 | { 783 | "cell_type": "markdown", 784 | "metadata": { 785 | "id": "Ym-9IZhSHabA" 786 | }, 787 | "source": [ 788 | "## Defaultdict" 789 | ] 790 | }, 791 | { 792 | "cell_type": "markdown", 793 | "metadata": { 794 | "id": "dJVyj9IvHejV" 795 | }, 796 | "source": [ 797 | "Словарь, где можно задать дефолтное значение для ключей, которых пока нет в словаре. При добавлении не надо использовать get или же проверять, есть ли ключ в словаре\n", 798 | "\n", 799 | "Работает полностью как словарь" 800 | ] 801 | }, 802 | { 803 | "cell_type": "code", 804 | "metadata": { 805 | "colab": { 806 | "base_uri": "https://localhost:8080/" 807 | }, 808 | "id": "S4dCDUDRFJa0", 809 | "outputId": "6ddc3256-5bc4-4e7d-f141-ccb2aec954b3" 810 | }, 811 | "source": [ 812 | "from collections import defaultdict\n", 813 | "\n", 814 | "d = defaultdict(int) # задаем тип значения по дефолту (если int - то это 0)\n", 815 | "s = ['ab', 'ab', 'bc', 'cd', 'ab']\n", 816 | "for elem in s:\n", 817 | " d[elem] += 1\n", 818 | "print(d)\n", 819 | "\n", 820 | "print('-' * 30)\n", 821 | "\n", 822 | "d = defaultdict(list) # задаем тип значения по дефолту (если int - то это 0)\n", 823 | "s = ['ab', 'ab', 'bc', 'cd', 'ab']\n", 824 | "for elem in s:\n", 825 | " d[elem].append(elem)\n", 826 | "print(d)\n", 827 | "\n", 828 | "print('-' * 30)\n", 829 | "\n", 830 | "d = defaultdict(lambda: '') # в качестве значения по дефолту можно использовать функцию\n", 831 | "s = ['ab', 'ab', 'bc', 'cd', 'ab']\n", 832 | "for elem in s:\n", 833 | " d[elem] += elem\n", 834 | "print(d)" 835 | ], 836 | "execution_count": null, 837 | "outputs": [ 838 | { 839 | "output_type": "stream", 840 | "name": "stdout", 841 | "text": [ 842 | "defaultdict(, {'ab': 3, 'bc': 1, 'cd': 1})\n", 843 | "------------------------------\n", 844 | "defaultdict(, {'ab': ['ab', 'ab', 'ab'], 'bc': ['bc'], 'cd': ['cd']})\n", 845 | "------------------------------\n", 846 | "defaultdict( at 0x7ff35d14e830>, {'ab': 'ababab', 'bc': 'bc', 'cd': 'cd'})\n" 847 | ] 848 | } 849 | ] 850 | }, 851 | { 852 | "cell_type": "markdown", 853 | "metadata": { 854 | "id": "qrLg4waSKBCh" 855 | }, 856 | "source": [ 857 | "# Itertools" 858 | ] 859 | }, 860 | { 861 | "cell_type": "markdown", 862 | "metadata": { 863 | "id": "9jCNYYPJKFW-" 864 | }, 865 | "source": [ 866 | "Itertools - библиотека с некоторыми полезными реализованными итераторами. Полезно при генерации последовательностей, создании комбинаций, перестановок, произведений" 867 | ] 868 | }, 869 | { 870 | "cell_type": "code", 871 | "metadata": { 872 | "colab": { 873 | "base_uri": "https://localhost:8080/" 874 | }, 875 | "id": "r1INzY7SKwXS", 876 | "outputId": "0f69f9ca-6d5d-456c-d70e-7fb6c9b7be75" 877 | }, 878 | "source": [ 879 | "from itertools import count, cycle, repeat\n", 880 | "\n", 881 | "# Арифметическая прогрессия\n", 882 | "\n", 883 | "i = count(10, 2)\n", 884 | "print(next(i))\n", 885 | "print(next(i))\n", 886 | "print(next(i))\n", 887 | "print(next(i))\n", 888 | "\n", 889 | "print('-' * 30)\n", 890 | "\n", 891 | "# Цикл\n", 892 | "\n", 893 | "i = cycle('ABC')\n", 894 | "print(next(i))\n", 895 | "print(next(i))\n", 896 | "print(next(i))\n", 897 | "print(next(i))\n", 898 | "print(next(i))\n", 899 | "print(next(i))\n", 900 | "print(next(i))\n", 901 | "print(next(i))\n", 902 | "\n", 903 | "print('-' * 30)\n", 904 | "\n", 905 | "# Повтор\n", 906 | "\n", 907 | "i = repeat('ABC', 5)\n", 908 | "print(next(i))\n", 909 | "print(next(i))\n", 910 | "print(next(i))\n", 911 | "print(next(i))\n", 912 | "print(next(i))" 913 | ], 914 | "execution_count": null, 915 | "outputs": [ 916 | { 917 | "output_type": "stream", 918 | "name": "stdout", 919 | "text": [ 920 | "10\n", 921 | "12\n", 922 | "14\n", 923 | "16\n", 924 | "------------------------------\n", 925 | "A\n", 926 | "B\n", 927 | "C\n", 928 | "A\n", 929 | "B\n", 930 | "C\n", 931 | "A\n", 932 | "B\n", 933 | "------------------------------\n", 934 | "ABC\n", 935 | "ABC\n", 936 | "ABC\n", 937 | "ABC\n", 938 | "ABC\n" 939 | ] 940 | } 941 | ] 942 | }, 943 | { 944 | "cell_type": "code", 945 | "metadata": { 946 | "colab": { 947 | "base_uri": "https://localhost:8080/" 948 | }, 949 | "id": "sCnRkCu3LUMC", 950 | "outputId": "197e7961-dc36-4ce6-8df3-171bad20b49b" 951 | }, 952 | "source": [ 953 | "from itertools import zip_longest, accumulate\n", 954 | "\n", 955 | "z = zip_longest('ABCD', 'xy', fillvalue='-')\n", 956 | "\n", 957 | "for a, b in z:\n", 958 | " print(a, b)\n", 959 | "\n", 960 | "print('-' * 30)\n", 961 | "\n", 962 | "a = accumulate([1, 2, 3, 4])\n", 963 | "print(next(a))\n", 964 | "print(next(a))\n", 965 | "print(next(a))\n", 966 | "print(next(a))\n" 967 | ], 968 | "execution_count": null, 969 | "outputs": [ 970 | { 971 | "output_type": "stream", 972 | "name": "stdout", 973 | "text": [ 974 | "A x\n", 975 | "B y\n", 976 | "C -\n", 977 | "D -\n", 978 | "------------------------------\n", 979 | "1\n", 980 | "3\n", 981 | "6\n", 982 | "10\n" 983 | ] 984 | } 985 | ] 986 | }, 987 | { 988 | "cell_type": "markdown", 989 | "metadata": { 990 | "id": "FttrJXZlMpnN" 991 | }, 992 | "source": [ 993 | "Но самое интересное - это комбинаторные итераторы:\n", 994 | "\n", 995 | "* product(iter, repeat) - repeat число декартово произведение элементов iter\n", 996 | "* permutations(iter, r) - все перестановки длины r из iter\n", 997 | "* combinations(iter, r) - все комбинации длины r из iter (упорядоченные)\n", 998 | "* combinations_with_replacement(iter, r) - все комбинации с повторениями длины r (упорядоченные)" 999 | ] 1000 | }, 1001 | { 1002 | "cell_type": "code", 1003 | "metadata": { 1004 | "colab": { 1005 | "base_uri": "https://localhost:8080/" 1006 | }, 1007 | "id": "HrmFcTymNjAS", 1008 | "outputId": "2fef013a-d9ba-40fe-902b-c0dae7a4f648" 1009 | }, 1010 | "source": [ 1011 | "from itertools import product, permutations, combinations, combinations_with_replacement\n", 1012 | "\n", 1013 | "a = product('ABCD', repeat=3)\n", 1014 | "print(next(a))\n", 1015 | "print(next(a))\n", 1016 | "print(next(a))\n", 1017 | "print(next(a))\n", 1018 | "\n", 1019 | "print('-' * 30)\n", 1020 | "\n", 1021 | "a = permutations([1, 2, 3], r=3)\n", 1022 | "print(next(a))\n", 1023 | "print(next(a))\n", 1024 | "print(next(a))\n", 1025 | "print(next(a))\n", 1026 | "print(next(a))\n", 1027 | "print(next(a))\n", 1028 | "\n", 1029 | "print('-' * 30)\n", 1030 | "\n", 1031 | "a = combinations('ABACD', r=3)\n", 1032 | "print(next(a))\n", 1033 | "print(next(a))\n", 1034 | "print(next(a))\n", 1035 | "print(next(a))\n", 1036 | "\n", 1037 | "print('-' * 30)\n", 1038 | "\n", 1039 | "a = combinations_with_replacement('ABCD', r=3)\n", 1040 | "print(next(a))\n", 1041 | "print(next(a))\n", 1042 | "print(next(a))\n", 1043 | "print(next(a))\n", 1044 | "\n", 1045 | "print('-' * 30)" 1046 | ], 1047 | "execution_count": null, 1048 | "outputs": [ 1049 | { 1050 | "output_type": "stream", 1051 | "name": "stdout", 1052 | "text": [ 1053 | "('A', 'A', 'A')\n", 1054 | "('A', 'A', 'B')\n", 1055 | "('A', 'A', 'C')\n", 1056 | "('A', 'A', 'D')\n", 1057 | "------------------------------\n", 1058 | "(1, 2, 3)\n", 1059 | "(1, 3, 2)\n", 1060 | "(2, 1, 3)\n", 1061 | "(2, 3, 1)\n", 1062 | "(3, 1, 2)\n", 1063 | "(3, 2, 1)\n", 1064 | "------------------------------\n", 1065 | "('A', 'B', 'A')\n", 1066 | "('A', 'B', 'C')\n", 1067 | "('A', 'B', 'D')\n", 1068 | "('A', 'A', 'C')\n", 1069 | "------------------------------\n", 1070 | "('A', 'A', 'A')\n", 1071 | "('A', 'A', 'B')\n", 1072 | "('A', 'A', 'C')\n", 1073 | "('A', 'A', 'D')\n", 1074 | "------------------------------\n" 1075 | ] 1076 | } 1077 | ] 1078 | }, 1079 | { 1080 | "cell_type": "markdown", 1081 | "source": [ 1082 | "# Попугай дня" 1083 | ], 1084 | "metadata": { 1085 | "id": "gMFY_bf533vm" 1086 | } 1087 | }, 1088 | { 1089 | "cell_type": "markdown", 1090 | "source": [ 1091 | "![Жако](https://petshop-vrn.ru/wp-content/uploads/6/c/a/6ca4dd99334ae553c70fbc4ed4165506.jpeg)" 1092 | ], 1093 | "metadata": { 1094 | "id": "16jPvyffWRlR" 1095 | } 1096 | }, 1097 | { 1098 | "cell_type": "markdown", 1099 | "source": [ 1100 | "А это Жако, или серый попугай. Считаются самыми умными попугаями в мире, потому что они способны не просто на подражание звуков (как это делают многие попугаи)\n", 1101 | "\n", 1102 | "В 1980-х годах ученая Ирэн Пепперберг проводила исследования по языковому мышлению различных животных, и одним из подопытных был серый попугай по имени Алекс. По результатам эксперимента Алекс мог произносить очень много слов, причем он верно отвечал на вопросы и в целом коммуницировал исходя не из подражания, а из логики. В целом было показано, что у него было мышление, как у шестилетнего ребенка, что стало полным открытием для ученых.\n", 1103 | "\n", 1104 | "Хотя, на самом деле, сравнивать мышление попугаев и людей сложно, потому что мышление животных и не должно быть похожим на человеческое" 1105 | ], 1106 | "metadata": { 1107 | "id": "l7vAW4LpWacC" 1108 | } 1109 | } 1110 | ] 1111 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Курс "Язык программирования Python" для 1 курса ФКН ВШЭ 2023-2024 год 2 | 3 | #### [Лекция 1: Ввод-вывод, типы данных](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_1.ipynb) 4 | #### [Лекция 2: Циклы и условия, ввод-вывод с файла](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_2.ipynb) 5 | #### [Лекция 3: Словари, множества](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_3.ipynb) 6 | #### [Лекция 4: Функции, рекурсии, декораторы](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_4.ipynb) 7 | #### [Лекция 5: Итераторы и генераторы](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_5.ipynb) 8 | #### [Лекция 6: Исключения и логирование](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_6.ipynb) 9 | #### [Лекция 7: ООП-1](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_7_8.ipynb) 10 | #### [Лекция 8: ООП-2](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_7_8.ipynb) 11 | #### [Лекция 9: Регулярные выражения, collections + itertools](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_9.ipynb) 12 | #### [Лекция 10-11: Numpy](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_10.ipynb) 13 | #### [Лекция 12: Pandas](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_11.ipynb) 14 | #### [Лекция 13: Matplotlib + seaborn](https://colab.research.google.com/github/Palladain/Python_1_HSE_2023/blob/main/Lecture_13.ipynb) 15 | #### Лекция 14: Requests 16 | --------------------------------------------------------------------------------