├── requirements.txt
├── Python теория.docx
├── images
├── image_1.png
├── image_10.png
├── image_11.png
├── image_12.png
├── image_13.png
├── image_14.png
├── image_15.png
├── image_16.png
├── image_17.png
├── image_18.png
├── image_19.png
├── image_2.png
├── image_20.png
├── image_21.png
├── image_22.png
├── image_23.png
├── image_3.png
├── image_4.png
├── image_5.png
├── image_6.png
├── image_7.png
├── image_8.png
└── image_9.png
├── TODO
├── .github
└── workflows
│ └── commit.yml
├── .gitignore
├── docx-to-md.py
└── README.md
/requirements.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/requirements.txt
--------------------------------------------------------------------------------
/Python теория.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/Python теория.docx
--------------------------------------------------------------------------------
/images/image_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_1.png
--------------------------------------------------------------------------------
/images/image_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_10.png
--------------------------------------------------------------------------------
/images/image_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_11.png
--------------------------------------------------------------------------------
/images/image_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_12.png
--------------------------------------------------------------------------------
/images/image_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_13.png
--------------------------------------------------------------------------------
/images/image_14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_14.png
--------------------------------------------------------------------------------
/images/image_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_15.png
--------------------------------------------------------------------------------
/images/image_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_16.png
--------------------------------------------------------------------------------
/images/image_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_17.png
--------------------------------------------------------------------------------
/images/image_18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_18.png
--------------------------------------------------------------------------------
/images/image_19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_19.png
--------------------------------------------------------------------------------
/images/image_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_2.png
--------------------------------------------------------------------------------
/images/image_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_20.png
--------------------------------------------------------------------------------
/images/image_21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_21.png
--------------------------------------------------------------------------------
/images/image_22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_22.png
--------------------------------------------------------------------------------
/images/image_23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_23.png
--------------------------------------------------------------------------------
/images/image_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_3.png
--------------------------------------------------------------------------------
/images/image_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_4.png
--------------------------------------------------------------------------------
/images/image_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_5.png
--------------------------------------------------------------------------------
/images/image_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_6.png
--------------------------------------------------------------------------------
/images/image_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_7.png
--------------------------------------------------------------------------------
/images/image_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_8.png
--------------------------------------------------------------------------------
/images/image_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_9.png
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 | yield from
2 | ['assert', 'async', 'await', 'class', 'raise']
3 | битовые операции
4 | match/case
5 | фикс чисел в math в конспекте
6 | Python имеет и встроенную команду round(). функция а не команда
7 | функция генераторов и итераторов
--------------------------------------------------------------------------------
/.github/workflows/commit.yml:
--------------------------------------------------------------------------------
1 | name: DOCX to Markdown
2 |
3 | on:
4 | push:
5 | branches: [ "main" ]
6 | pull_request:
7 | branches: [ "main" ]
8 |
9 | jobs:
10 | convert:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - name: Checkout repo
15 | uses: actions/checkout@v4
16 |
17 | - name: Set up Python
18 | uses: actions/setup-python@v5
19 | with:
20 | python-version: "3.11"
21 |
22 | - name: Install dependencies
23 | run: |
24 | python -m pip install --upgrade pip
25 | pip install python-docx
26 |
27 | - name: Run DOCX to Markdown converter
28 | run: python docx-to-md.py
29 |
30 | - name: Move converted files to repo root
31 | run: |
32 | shopt -s dotglob
33 | for f in MarkdownOutput/*; do
34 | mv "$f" .
35 | done
36 |
37 | - name: Commit and push changes
38 | env:
39 | GH_TOKEN: ${{ secrets.GH_TOKEN }}
40 | run: |
41 | git config user.name "github-actions[bot]"
42 | git config user.email "github-actions[bot]@users.noreply.github.com"
43 | git add .
44 | git commit -m "Auto-update Markdown from DOCX" || echo "No changes"
45 | git push https://x-access-token:$GH_TOKEN@github.com/${{ github.repository }} HEAD:main
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[codz]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | share/python-wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 | MANIFEST
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .nox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | *.py.cover
50 | .hypothesis/
51 | .pytest_cache/
52 | cover/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | .pybuilder/
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # IPython
82 | profile_default/
83 | ipython_config.py
84 |
85 | # pyenv
86 | # For a library or package, you might want to ignore these files since the code is
87 | # intended to run in multiple environments; otherwise, check them in:
88 | # .python-version
89 |
90 | # pipenv
91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
94 | # install all needed dependencies.
95 | #Pipfile.lock
96 |
97 | # UV
98 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99 | # This is especially recommended for binary packages to ensure reproducibility, and is more
100 | # commonly ignored for libraries.
101 | #uv.lock
102 |
103 | # poetry
104 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105 | # This is especially recommended for binary packages to ensure reproducibility, and is more
106 | # commonly ignored for libraries.
107 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108 | #poetry.lock
109 | #poetry.toml
110 |
111 | # pdm
112 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113 | # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114 | # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115 | #pdm.lock
116 | #pdm.toml
117 | .pdm-python
118 | .pdm-build/
119 |
120 | # pixi
121 | # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122 | #pixi.lock
123 | # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124 | # in the .venv directory. It is recommended not to include this directory in version control.
125 | .pixi
126 |
127 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128 | __pypackages__/
129 |
130 | # Celery stuff
131 | celerybeat-schedule
132 | celerybeat.pid
133 |
134 | # SageMath parsed files
135 | *.sage.py
136 |
137 | # Environments
138 | .env
139 | .envrc
140 | .venv
141 | env/
142 | venv/
143 | ENV/
144 | env.bak/
145 | venv.bak/
146 |
147 | # Spyder project settings
148 | .spyderproject
149 | .spyproject
150 |
151 | # Rope project settings
152 | .ropeproject
153 |
154 | # mkdocs documentation
155 | /site
156 |
157 | # mypy
158 | .mypy_cache/
159 | .dmypy.json
160 | dmypy.json
161 |
162 | # Pyre type checker
163 | .pyre/
164 |
165 | # pytype static type analyzer
166 | .pytype/
167 |
168 | # Cython debug symbols
169 | cython_debug/
170 |
171 | # PyCharm
172 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
173 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
174 | # and can be added to the global gitignore or merged into this file. For a more nuclear
175 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
176 | #.idea/
177 |
178 | # Abstra
179 | # Abstra is an AI-powered process automation framework.
180 | # Ignore directories containing user credentials, local state, and settings.
181 | # Learn more at https://abstra.io/docs
182 | .abstra/
183 |
184 | # Visual Studio Code
185 | # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186 | # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187 | # and can be added to the global gitignore or merged into this file. However, if you prefer,
188 | # you could uncomment the following to ignore the entire vscode folder
189 | # .vscode/
190 |
191 | # Ruff stuff:
192 | .ruff_cache/
193 |
194 | # PyPI configuration file
195 | .pypirc
196 |
197 | # Cursor
198 | # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
199 | # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
200 | # refer to https://docs.cursor.com/context/ignore-files
201 | .cursorignore
202 | .cursorindexingignore
203 |
204 | # Marimo
205 | marimo/_static/
206 | marimo/_lsp/
207 | __marimo__/
208 |
--------------------------------------------------------------------------------
/docx-to-md.py:
--------------------------------------------------------------------------------
1 | import re
2 | import docx
3 | import os
4 |
5 | # === DOCX TO MARKDOWN ===
6 |
7 |
8 | def sanitize_anchor(text):
9 | anchor = re.sub(r"[^\w\s-]", "", text.lower())
10 | anchor = re.sub(r"[\s-]+", "-", anchor)
11 | return anchor.strip("-")
12 |
13 |
14 | def is_list_paragraph(paragraph):
15 | """Проверка, является ли параграф элементом списка в Word."""
16 | p = paragraph._p
17 | numPr = p.find(".//w:numPr", p.nsmap)
18 | return numPr is not None
19 |
20 |
21 | def add_two_spaces(line):
22 | return line + " "
23 |
24 |
25 | def docx_to_markdown(docx_path, output_dir):
26 | os.makedirs(output_dir, exist_ok=True)
27 | images_dir = os.path.join(output_dir, "images")
28 | os.makedirs(images_dir, exist_ok=True)
29 |
30 | doc = docx.Document(docx_path)
31 | markdown_lines = []
32 | current_code_block = []
33 | in_code_block = False
34 | image_counter = 1
35 |
36 | # Собираем картинки
37 | image_parts = {}
38 | for rel in doc.part.rels.values():
39 | if rel.target_ref and "image" in rel.target_ref:
40 | image_parts[rel.rId] = rel.target_part
41 |
42 | for element in doc.element.body:
43 | if element.tag.endswith("p"):
44 | paragraph = docx.text.paragraph.Paragraph(element, doc)
45 |
46 | # Изображения
47 | if paragraph._element.xpath(".//pic:pic"):
48 | for run in paragraph.runs:
49 | if run._element.xpath(".//pic:pic"):
50 | blip = run._element.xpath(".//a:blip/@r:embed")[0]
51 | if blip in image_parts:
52 | img_path = os.path.join(
53 | images_dir, f"image_{image_counter}.png"
54 | )
55 | with open(img_path, "wb") as f:
56 | f.write(image_parts[blip].blob)
57 | markdown_lines.append(
58 | add_two_spaces(
59 | f""
60 | )
61 | )
62 | image_counter += 1
63 | continue
64 |
65 | is_code_font = all(
66 | run.font and run.font.name == "Cascadia Mono" for run in paragraph.runs
67 | )
68 | has_content = bool(paragraph.text.strip())
69 |
70 | if not has_content:
71 | if in_code_block and is_code_font:
72 | current_code_block.append("")
73 | else:
74 | markdown_lines.append("")
75 | continue
76 |
77 | if is_code_font:
78 | if not in_code_block and current_code_block:
79 | code_text = "\n".join(current_code_block)
80 | markdown_lines.append(
81 | add_two_spaces(f"```python\n{code_text}\n```")
82 | )
83 | current_code_block = []
84 | in_code_block = True
85 | current_code_block.append(add_two_spaces(paragraph.text))
86 | else:
87 | if in_code_block and current_code_block:
88 | code_text = "\n".join(current_code_block)
89 | markdown_lines.append(
90 | add_two_spaces(f"```python\n{code_text}\n```")
91 | )
92 | current_code_block = []
93 | in_code_block = False
94 |
95 | paragraph_text = ""
96 | runs = paragraph.runs
97 | i = 0
98 | while i < len(runs):
99 | run = runs[i]
100 | if (
101 | run.font
102 | and run.font.name == "Cascadia Mono"
103 | and run.text.strip()
104 | ):
105 | code_parts = [run.text]
106 | j = i + 1
107 | while j < len(runs):
108 | next_run = runs[j]
109 | if (
110 | next_run.font and next_run.font.name == "Cascadia Mono"
111 | ) or (
112 | next_run.text == " "
113 | and j + 1 < len(runs)
114 | and runs[j + 1].font
115 | and runs[j + 1].font.name == "Cascadia Mono"
116 | ):
117 | code_parts.append(next_run.text)
118 | j += 1
119 | else:
120 | break
121 | paragraph_text += f"`{''.join(code_parts)}`"
122 | i = j
123 | else:
124 | paragraph_text += run.text
125 | i += 1
126 |
127 | paragraph_text = add_two_spaces(paragraph_text.rstrip())
128 |
129 | if paragraph.style.name.startswith("Heading"):
130 | level = int(paragraph.style.name.split()[-1])
131 | clean_text = paragraph_text.strip()
132 | markdown_lines.append(add_two_spaces(f"{'#' * level} {clean_text}"))
133 | elif is_list_paragraph(paragraph):
134 | markdown_lines.append(add_two_spaces(f"- {paragraph_text.strip()}"))
135 | else:
136 | markdown_lines.append(add_two_spaces(paragraph_text))
137 |
138 | elif element.tag.endswith("tbl"):
139 | table = docx.table.Table(element, doc)
140 | num_cols = len(table.columns)
141 | header = [add_two_spaces(cell.text.strip()) for cell in table.rows[0].cells]
142 | markdown_lines.append(add_two_spaces("| " + " | ".join(header) + " |"))
143 | markdown_lines.append(
144 | add_two_spaces("|" + "|".join(["---"] * num_cols) + "|")
145 | )
146 |
147 | for row in table.rows[1:]:
148 | row_data = [
149 | add_two_spaces(cell.text.strip().replace("\n", "
"))
150 | for cell in row.cells
151 | ]
152 | markdown_lines.append(
153 | add_two_spaces("| " + " | ".join(row_data) + " |")
154 | )
155 |
156 | if current_code_block:
157 | code_text = "\n".join(current_code_block)
158 | markdown_lines.append(add_two_spaces(f"```python\n{code_text}\n```"))
159 |
160 | # Оглавление
161 | toc = [add_two_spaces("## Оглавление")]
162 | headers = []
163 | for line in markdown_lines:
164 | if line.startswith("#") and not line.startswith("## Оглавление"):
165 | level = len(line.split()[0])
166 | title = " ".join(line.split()[1:])
167 | headers.append((level, title))
168 |
169 | anchor_counts = {}
170 | for level, title in headers:
171 | anchor = sanitize_anchor(title)
172 | if anchor in anchor_counts:
173 | anchor_counts[anchor] += 1
174 | anchor = f"{anchor}-{anchor_counts[anchor]}"
175 | else:
176 | anchor_counts[anchor] = 1
177 | indent = " " * (level - 1)
178 | toc.append(add_two_spaces(f"{indent}- [{title}](#{anchor})"))
179 |
180 | output_path = os.path.join(output_dir, "README.md")
181 | with open(output_path, "w", encoding="utf-8") as f:
182 | f.write("\n".join(toc + ["\n"] + markdown_lines))
183 |
184 | return output_path
185 |
186 |
187 | # === Использование ===
188 | docx_path = "Python теория.docx"
189 | output_dir = "MarkdownOutput"
190 | result_path = docx_to_markdown(docx_path, output_dir)
191 | print(f"Markdown сохранен в: {result_path}")
192 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Оглавление
2 | - [Ввод-вывод](#ввод-вывод)
3 | - [Базовые команды](#базовые-команды)
4 | - [sep, end](#sep-end)
5 | - [Арифметика и её приоритеты](#арифметика-и-её-приоритеты)
6 | - [Логические операторы и их приоритеты](#логические-операторы-и-их-приоритеты)
7 | - [If-elif-else](#if-elif-else)
8 | - [Операторы сравнения](#операторы-сравнения)
9 | - [or, and, not](#or-and-not)
10 | - [Типы данных](#типы-данных)
11 | - [Числовые типы данных](#числовые-типы-данных)
12 | - [Строковый тип данных](#строковый-тип-данных)
13 | - [Модуль math](#модуль-math)
14 | - [Циклы](#циклы)
15 | - [For](#for)
16 | - [Частые сценарии](#частые-сценарии)
17 | - [While](#while)
18 | - [while: break, continue, else](#while-break-continue-else)
19 | - [Вложенные циклы](#вложенные-циклы)
20 | - [Строки](#строки)
21 | - [Индексация строк](#индексация-строк)
22 | - [Вывод символов строки](#вывод-символов-строки)
23 | - [Срезы строк](#срезы-строк)
24 | - [Методы строк](#методы-строк)
25 | - [partition()](#partition)
26 | - [format(); format_map()](#format-format_map)
27 | - [f-строки](#f-строки)
28 | - [Строки в памяти компьютера](#строки-в-памяти-компьютера)
29 | - [Сравнение строк](#сравнение-строк)
30 | - [Списки](#списки)
31 | - [Создание списка](#создание-списка)
32 | - [Основы (len, sum, min, max, in)](#основы-len-sum-min-max-in)
33 | - [Добавление элементов](#добавление-элементов)
34 | - [Объединение списков](#объединение-списков)
35 | - [Удаление элементов](#удаление-элементов)
36 | - [Вывод элементов списка](#вывод-элементов-списка)
37 | - [split(), join()](#split-join)
38 | - [Методы списков](#методы-списков)
39 | - [Сортировка списков](#сортировка-списков)
40 | - [Генераторы списков; списочные выражения](#генераторы-списков-списочные-выражения)
41 | - [Нахождение чисел палиндромов](#нахождение-чисел-палиндромов)
42 | - [Методы сортировки списков](#методы-сортировки-списков)
43 | - [Тип данных bool и NoneType](#тип-данных-bool-и-nonetype)
44 | - [bool](#bool)
45 | - [NoneType](#nonetype)
46 | - [Вложенные списки](#вложенные-списки)
47 | - [Основы](#основы)
48 | - [Матрицы, ljust(), rjust()](#матрицы-ljust-rjust)
49 | - [Кортежи](#кортежи)
50 | - [Введение](#введение)
51 | - [Основы](#основы-2)
52 | - [Сравнение кортежей](#сравнение-кортежей)
53 | - [Сортировка кортежей](#сортировка-кортежей)
54 | - [Распаковка кортежей; “хвосты”](#распаковка-кортежей-хвосты)
55 | - [Множества](#множества)
56 | - [Множества в математике](#множества-в-математике)
57 | - [Пустое множество](#пустое-множество)
58 | - [Числовые множества](#числовые-множества)
59 | - [Операции над множествами](#операции-над-множествами)
60 | - [Диаграммы Эйлера-Венна при решении задач](#диаграммы-эйлера-венна-при-решении-задач)
61 | - [Введение в множества в Python](#введение-в-множества-в-python)
62 | - [Создание множества](#создание-множества)
63 | - [Вывод множества](#вывод-множества)
64 | - [set()](#set)
65 | - [Основы работы с множествами](#основы-работы-с-множествами)
66 | - [Перебор элементов множества и распаковка](#перебор-элементов-множества-и-распаковка)
67 | - [Сравнение множеств](#сравнение-множеств)
68 | - [Методы множеств](#методы-множеств)
69 | - [Генераторы множеств](#генераторы-множеств)
70 | - [frozenset](#frozenset)
71 | - [Словари](#словари)
72 | - [Введение](#введение-2)
73 | - [Создание словаря](#создание-словаря)
74 | - [Создание пустого словаря](#создание-пустого-словаря)
75 | - [Важные детали](#важные-детали)
76 | - [Основы (len, sum, min, max, in)](#основы-len-sum-min-max-in-2)
77 | - [Сравнение словарей](#сравнение-словарей)
78 | - [Перебор элементов словаря](#перебор-элементов-словаря)
79 | - [Распаковка словарей](#распаковка-словарей)
80 | - [Методы keys(), values(), items()](#методы-keys-values-items)
81 | - [Сортировка словарей](#сортировка-словарей)
82 | - [Методы словарей](#методы-словарей)
83 | - [Генераторы словарей](#генераторы-словарей)
84 | - [Вложенные словари](#вложенные-словари)
85 | - [Модули random, string, Метод Монте-Карло, Bogosort](#модули-random-string-метод-монте-карло-bogosort)
86 | - [Модуль random](#модуль-random)
87 | - [Модуль string](#модуль-string)
88 | - [Метод Монте-Карло](#метод-монте-карло)
89 | - [Bogosort](#bogosort)
90 | - [Модули decimal, fractions и complex](#модули-decimal-fractions-и-complex)
91 | - [Модуль decimal: введение](#модуль-decimal-введение)
92 | - [Создание Decimal чисел](#создание-decimal-чисел)
93 | - [Арифметические операции над Decimal числами](#арифметические-операции-над-decimal-числами)
94 | - [Математические функции Decimal чисел](#математические-функции-decimal-чисел)
95 | - [Работа с контекстом Decimal чисел](#работа-с-контекстом-decimal-чисел)
96 | - [Точность Decimal чисел](#точность-decimal-чисел)
97 | - [Округление Decimal чисел](#округление-decimal-чисел)
98 | - [Сравнение float и Decimal чисел](#сравнение-float-и-decimal-чисел)
99 | - [Важные примечания для decimal](#важные-примечания-для-decimal)
100 | - [Модуль fractions: введение](#модуль-fractions-введение)
101 | - [Тип данных Fraction](#тип-данных-fraction)
102 | - [Создание Fraction чисел](#создание-fraction-чисел)
103 | - [Основы типа данных Fraction](#основы-типа-данных-fraction)
104 | - [Сравнение Fraction чисел](#сравнение-fraction-чисел)
105 | - [Арифметические операции над Fraction числами](#арифметические-операции-над-fraction-числами)
106 | - [Математические функции](#математические-функции)
107 | - [Свойства numerator и denominator, as_integer_ratio()](#свойства-numerator-и-denominator-as_integer_ratio)
108 | - [Метод limit_denominator()](#метод-limit_denominator)
109 | - [Комплексные числа: введение](#комплексные-числа-введение)
110 | - [Комплексные числа в математике](#комплексные-числа-в-математике)
111 | - [Комплексные числа в Python](#комплексные-числа-в-python)
112 | - [Создание комплексных чисел](#создание-комплексных-чисел)
113 | - [Арифметические операции над комплексными числами](#арифметические-операции-над-комплексными-числами)
114 | - [Методы и свойства комплексных чисел](#методы-и-свойства-комплексных-чисел)
115 | - [cmath](#cmath)
116 | - [Модуль turtle](#модуль-turtle)
117 | - [Введение в turtle](#введение-в-turtle)
118 | - [Рисование отрезков прямой](#рисование-отрезков-прямой)
119 | - [Поворот черепашки](#поворот-черепашки)
120 | - [Изменение внешнего вида черепашки](#изменение-внешнего-вида-черепашки)
121 | - [Поднятие и опускание пера](#поднятие-и-опускание-пера)
122 | - [Рисование кругов и точек](#рисование-кругов-и-точек)
123 | - [Изменение размера пера](#изменение-размера-пера)
124 | - [Изменение цвета рисунка](#изменение-цвета-рисунка)
125 | - [Изменение цвета фона](#изменение-цвета-фона)
126 | - [Создание штампа](#создание-штампа)
127 | - [Возвращение экрана в исходное состояние](#возвращение-экрана-в-исходное-состояние)
128 | - [Размер окна](#размер-окна)
129 | - [Перемещение черепашки в заданную позицию](#перемещение-черепашки-в-заданную-позицию)
130 | - [Получение текущей позиции черепашки](#получение-текущей-позиции-черепашки)
131 | - [Сокрытие черепашки](#сокрытие-черепашки)
132 | - [Управление скоростью анимации черепахи](#управление-скоростью-анимации-черепахи)
133 | - [Вывод текста в графическое окно](#вывод-текста-в-графическое-окно)
134 | - [Заполнение геометрических фигур](#заполнение-геометрических-фигур)
135 | - [Создание нескольких черепашек](#создание-нескольких-черепашек)
136 | - [Отслеживание нажатия клавиш](#отслеживание-нажатия-клавиш)
137 | - [Отслеживание нажатия мыши](#отслеживание-нажатия-мыши)
138 | - [Функции](#функции)
139 | - [Функции без параметров](#функции-без-параметров)
140 | - [Функции с параметрами](#функции-с-параметрами)
141 | - [Глобальные, нелокальные и локальные переменные](#глобальные-нелокальные-и-локальные-переменные)
142 | - [Функции с возвратом значения](#функции-с-возвратом-значения)
143 | - [Позиционные и именованные аргументы](#позиционные-и-именованные-аргументы)
144 | - [Необязательные аргументы](#необязательные-аргументы)
145 | - [Изменяемые типы в качестве значений по умолчанию](#изменяемые-типы-в-качестве-значений-по-умолчанию)
146 | - [Переменное количество аргументов (*args, **kwargs)](#переменное-количество-аргументов-args-kwargs)
147 | - [Передача аргументов в форме списка и кортежа](#передача-аргументов-в-форме-списка-и-кортежа)
148 | - [Получение именованных аргументов в виде словаря](#получение-именованных-аргументов-в-виде-словаря)
149 | - [Keyword-only и positional-only аргументы](#keyword-only-и-positional-only-аргументы)
150 | - [Функции как объекты](#функции-как-объекты)
151 | - [Функции в качестве аргументов других функций](#функции-в-качестве-аргументов-других-функций)
152 | - [key в min(), max(), sort(), sorted()](#key-в-min-max-sort-sorted)
153 | - [Функции в качестве возвращаемых значений других функций (вложенные функции)](#функции-в-качестве-возвращаемых-значений-других-функций-вложенные-функции)
154 | - [Функции высшего порядка](#функции-высшего-порядка)
155 | - [map()](#map)
156 | - [filter()](#filter)
157 | - [reduce()](#reduce)
158 | - [Модуль operator](#модуль-operator)
159 | - [Анонимные функции (lambda): введение](#анонимные-функции-lambda-введение)
160 | - [Анонимные функции (lambda): основы, тернарный оператор](#анонимные-функции-lambda-основы-тернарный-оператор)
161 | - [all(), any()](#all-any)
162 | - [enumerate()](#enumerate)
163 | - [zip()](#zip)
164 | - [Рекурсия](#рекурсия)
165 | - [Декораторы](#декораторы)
166 | - [Работа с файлами](#работа-с-файлами)
167 | - [Введение](#введение-3)
168 | - [languages.txt](#languagestxt)
169 | - [Открытие файлов](#открытие-файлов)
170 | - [Указание места расположения файла, сырые строки](#указание-места-расположения-файла-сырые-строки)
171 | - [Кодировка](#кодировка)
172 | - [Закрытие файлов](#закрытие-файлов)
173 | - [read(), readline(), readlines()](#read-readline-readlines)
174 | - [Бинарные файлы](#бинарные-файлы)
175 | - [Свойства файла](#свойства-файла)
176 | - [Позиция в файле (курсор)](#позиция-в-файле-курсор)
177 | - [seek(), tell()](#seek-tell)
178 | - [Менеджер контекста](#менеджер-контекста)
179 | - [write(), writelines(), запись в файл при помощи print()](#write-writelines-запись-в-файл-при-помощи-print)
180 | - [Интересные штуки](#интересные-штуки)
181 | - [Числовая угадайка](#числовая-угадайка)
182 | - [Магический шар 8](#магический-шар-8)
183 | - [Генератор безопасных паролей](#генератор-безопасных-паролей)
184 | - [Калькулятор систем счисления (bin(), oct(), hex())](#калькулятор-систем-счисления-bin-oct-hex)
185 | - [Угадайка слов](#угадайка-слов)
186 | - [Не вошедшее в конспект](#не-вошедшее-в-конспект)
187 | - [Исключения (try-except-else-finally)](#исключения-try-except-else-finally)
188 | - [Итераторы и генераторы](#итераторы-и-генераторы)
189 | - [Малоизвестные (или не мало) функции](#малоизвестные-или-не-мало-функции)
190 | - [Спецификаторы](#спецификаторы)
191 | - [Спецсимволы и экранирование](#спецсимволы-и-экранирование)
192 | - [Неявная конкатенация](#неявная-конкатенация)
193 | - [Моржовый оператор](#моржовый-оператор)
194 | - [Присвоение цепочкой](#присвоение-цепочкой)
195 | - [Константы](#константы)
196 | - [Docstrings (Докстринги)](#docstrings-докстринги)
197 | - [Многоточие (…) как объект](#многоточие-как-объект)
198 | - [Атрибуты функций](#атрибуты-функций)
199 | - [locals(), globals()](#locals-globals)
200 | - [maketrans(), translate()](#maketrans-translate)
201 |
202 |
203 | Copyright (c) 2025 FerrumVega
204 | В конспекте использованы примеры и картинки из курсов https://stepik.org/course/58852 и https://stepik.org/course/68343.
205 | # Ввод-вывод
206 | ## Базовые команды
207 | Для ввода используется команда `input()`
208 | Для вывода команда `print()`
209 |
210 | Для присвоения переменной значения используют знак `=`
211 | ```python
212 | a = 5
213 | print(a)
214 | >>> 5
215 | ```
216 | ## sep, end
217 | С помощью `sep `и `end `можно установить знак между аргументами и конец строки в `print() `
218 | Пример:
219 | ```python
220 | print("Hello", "World", sep="*", end="/")
221 | >>> Hello*World/
222 |
223 | ```
224 | ## Арифметика и её приоритеты
225 | ```python
226 | + # сложение
227 | - # вычитание
228 | / # деление
229 | * # умножение
230 | ** # возведение в степень
231 | % # остаток от деления
232 | // # целочисленное деление
233 | ```
234 | Приоритеты (сверху самый высокий):
235 | ```python
236 | 1. ()
237 | 2. **
238 | 3. - (унарный минус)
239 | 4. *, /, //, %
240 | 5. +, -
241 |
242 |
243 | ```
244 | # Логические операторы и их приоритеты
245 | ## If-elif-else
246 | ```python
247 | answer = input('Какой язык программирования мы изучаем?')
248 |
249 | if answer == 'Python':
250 | print('Верно! Мы ботаем Python =)')
251 | print('Python - отличный язык!')
252 | elif answer == "C++":
253 | print('C++ тоже уважаем :)')
254 | else:
255 | print('Не знаю такого :(')
256 | ```
257 | ## Операторы сравнения
258 | | Выражение | Описание |
259 | |---|---|
260 | | if x > 7 | если x больше 7 |
261 | | if x < 7 | если x меньше 7 |
262 | | if x >= 7 | если x больше либо равен 7 |
263 | | if x <= 7 | если x меньше либо равен 7 |
264 | | if x == 7 | если x равен 7 |
265 | | if x != 7 | если x не равен 7 |
266 |
267 | Также можно использовать цепочки: `a == b == c`
268 |
269 | ## or, and, not
270 | ```python
271 | or # логическое сложение
272 | and # логическое умножение
273 | not # логическое отрицание
274 | ```
275 | Приоритеты (сверху самый высокий):
276 | ```python
277 | 1. not
278 | 2. and
279 | 3. or
280 |
281 | ```
282 | # Типы данных
283 | ## Числовые типы данных
284 | ```python
285 | int(n) # целочисленный тип данных (1)
286 | float(n) # число с плавающей точкой (0.1)
287 | max(a, b ... n) # максимальное число
288 | min(a, b ... n) # минимальное число
289 | abs(n) # абсолютная величина числа (модуль)
290 |
291 | ```
292 | Существует функция `divmod()`, которая возвращает кортеж из целочисленного частного x и y, и остатка от целочисленного частного из x и y:
293 | ```python
294 | print(divmod(5, 2))
295 | >>> (2, 1)
296 | ```
297 | ## Строковый тип данных
298 | ```python
299 | str("string") # преобразование в строку
300 | len("string") # длина строки
301 |
302 | print("ab"+"bc") # конкатенация (сложение строк)
303 | >>> abbc
304 |
305 | print("Hi" * 4) # умножение строки
306 | >>> HiHiHiHi
307 |
308 | text = """
309 | многострочный текст выделяется
310 | тройными кавычками
311 | """
312 |
313 | print("ab" in "abc")
314 | >>> True
315 | print("ac" in "abc")
316 | >>> False
317 | print("AB" in "abc")
318 | >>> False # in чувствителен к регистру
319 |
320 | ```
321 | ## Модуль math
322 | Существует 2 вида импорта модулей:
323 | ```python
324 | 1. import math
325 | 2. from math import *
326 | ```
327 | При использовании первого нужно использовать команды так:
328 | ```python
329 | math.sqrt(25)
330 | ```
331 | При использовании второго:
332 | ```python
333 | sqrt(25)
334 | ```
335 | Второй метод проще, но при нём могут возникнуть конфликты из-за одинаковых команд в разных модулях
336 | Также можно импортировать всего несколько команд, а не все из модуля:
337 | ```python
338 | from math import sqrt
339 | sqrt(25)
340 |
341 |
342 | ```
343 | Список функций модуля math
344 | | Функция | Описание |
345 | |---|---|
346 | | Округления | |
347 | | int() | Округляет число в сторону нуля |
348 | | round(x) | Округляет число x до ближайшего целого. Если дробная часть числа равна 0.50.5, то число округляется до ближайшего четного числа (банковское округление) |
349 | | round(x, n) | Округляет число x до n знаков после точки |
350 | | floor(x) | Округляет число x вниз («пол») |
351 | | ceil(x) | Округляет число x вверх («потолок») |
352 | | abs(x) | Модуль числа x (абсолютная величина) |
353 | | Корни, логарифмы, степени и факториал | |
354 | | sqrt(x) | Квадратный корень числа x |
355 | | pow(x, n) | Возведение числа x в степень n |
356 | | log(x) | Натуральный логарифм числа x. Основание натурального логарифма равно числу e |
357 | | log10(x) | Десятичный логарифм числа x. Основание десятичного логарифма равно числу 10 |
358 | | log(x, b) | Логарифм числа x по основанию b |
359 | | factorial(n) | Факториал натурального числа n |
360 | | Тригонометрия | |
361 | | degrees(x) | Преобразует угол x, заданный в радианах, в градусы |
362 | | radians(x) | Преобразует угол x, заданный в градусах, в радианы |
363 | | cos(x) | Косинус угла x, задаваемого в радианах |
364 | | sin(x) | Синус угла x, задаваемого в радианах |
365 | | tan(x) | Тангенс угла x, задаваемого в радианах |
366 | | acos(x) | Возвращает угол в радианах от 0 до π, cos которого равен x |
367 | | asin(x) | Возвращает угол в радианах от −π2−2π до π22π, sin которого равен x |
368 | | atan(x) | Возвращает угол в радианах от −π2−2π до π22π, tan которого равен x |
369 | | atan2(y, x) | Полярный угол (в радианах) точки с координатами (x, y) |
370 |
371 | Python имеет и встроенную команду `round().`
372 | # Циклы
373 | ## For
374 | for перебирает все значения из итератора и заполняет переменную текущим значением.
375 | С одним аргументом (от нуля до n-1):
376 | ```python
377 | for i in range(10):
378 | print(i)
379 | >>> 0
380 | >>> 1
381 | >>> 2
382 | >>> 3
383 | >>> 4
384 | >>> 5
385 | >>> 6
386 | >>> 7
387 | >>> 8
388 | >>> 9
389 | ```
390 | С двумя аргументами (от m до n-1):
391 | ```python
392 | for i in range(1, 10):
393 | print(i)
394 | >>> 1
395 | >>> 2
396 | >>> 3
397 | >>> 4
398 | >>> 5
399 | >>> 6
400 | >>> 7
401 | >>> 8
402 | >>> 9
403 | ```
404 | С тремя аргументами (от m до n-1 с шагом k):
405 | ```python
406 | for i in range(1, 10, 2): # третий аргумент - величина шага
407 | print(i)
408 | >>> 1
409 | >>> 3
410 | >>> 5
411 | >>> 7
412 | >>> 9
413 |
414 | ```
415 | ## Частые сценарии
416 | - Подсчёт количества
417 | ```python
418 | counter = 0
419 | for _ in range(10):
420 | num = int(input())
421 | if num > 10:
422 | counter = counter + 1
423 |
424 | print('Было введено', counter, 'чисел, больших 10.')
425 |
426 | ```
427 | - Обмен значений переменных
428 | Вместо:
429 | ```python
430 | temp = x
431 | x = y
432 | y = temp
433 | ```
434 | Можно использовать:
435 | ```python
436 | x, y = y, x
437 |
438 | ```
439 | - Сигнальные метки
440 | ```python
441 | num = int(input())
442 | flag = True
443 |
444 | for i in range(2, num):
445 | if num % i == 0: # если исходное число делится на какое-либо отличное от 1 и самого себя
446 | flag = False
447 |
448 | if num == 1:
449 | print('Это единица, она не простая и не составная')
450 | elif flag == True:
451 | print('Число простое')
452 | else:
453 | print('Число составное')
454 |
455 | ```
456 | - Максимум и минимум
457 | ```python
458 | largest = 0
459 | for _ in range(10):
460 | num = int(input())
461 | if num > largest:
462 | largest = num
463 |
464 | print('Наибольшее число равно', largest)
465 |
466 | ```
467 | - Расширенные операторы присваивания
468 | | Оператор | Пример использования | Эквивалент |
469 | |---|---|---|
470 | | += | x += 5 | x = x + 5 |
471 | | -= | x -= 2 | x = x - 2 |
472 | | *= | x *= 10 | x = x * 10 |
473 | | /= | x /= 4 | x = x / 4 |
474 | | //= | x //= 4 | x = x // 4 |
475 | | %= | x %= 4 | x = x % 4 |
476 |
477 | ## While
478 | While выполняет команды внутри себя пока условие(-я) выполняется(-ются)
479 | - Обработка цифр числа:
480 | ```python
481 | n = int(input())
482 | while n != 0: # пока в числе есть цифры
483 | last_digit = n % 10 # получить последнюю цифру
484 | # код обработки последней цифры
485 | n = n // 10 # удалить последнюю цифру из числа
486 |
487 | ```
488 | - «До остановки»:
489 | ```python
490 | text = input()
491 | total = 0
492 | while text != "stop":
493 | total += int(text)
494 | text = input()
495 | print("Сумма чисел равна", total)
496 |
497 | ```
498 | ## while: break, continue, else
499 | `break `завершает цикл
500 | Проверка числа на простоту:
501 | ```python
502 | num = int(input())
503 | flag = True
504 |
505 | for i in range(2, num):
506 | if num % i == 0: # если исходное число делится на какое-либо отличное от 1 и самого себя
507 | flag = False
508 | break # останавливаем цикл если встретился делитель числа
509 | if flag: # эквивалентно if flag == True:
510 | print('Число простое')
511 | else:
512 | print('Число составное')
513 |
514 | ```
515 | `continue `позволяет перейти к следующей итерации цикла `for `или `while `до завершения всех команд в теле цикла.
516 | Программа, которая выводит все числа от 1 до 100, кроме чисел 7, 17, 29 и 78:
517 | ```python
518 | for i in range(1, 101):
519 | if i == 7 or i == 17 or i == 29 or i == 78:
520 | continue # переходим на следующую итерацию
521 | print(i)
522 |
523 | ```
524 | Python допускает необязательный блок `else `в конце циклов `while` и `for`. Это уникальная особенность Python, не встречающаяся в большинстве других языков программирования. `else `выполнится, если цикл завершился без `break`. Синтаксис такой конструкции следующий:
525 | ```python
526 | while условие:
527 | блок кода1
528 | else:
529 | блок кода2
530 |
531 | # или
532 |
533 | for i in range(10):
534 | блок кода1
535 | else:
536 | блок кода2
537 | ```
538 | Пример:
539 | ```python
540 | n = 5
541 | while n > 0:
542 | n -= 1
543 | print(n)
544 | else:
545 | print("Цикл завершен.")
546 |
547 | ```
548 | ## Вложенные циклы
549 | ```python
550 | for hours in range(24):
551 | for minutes in range(60):
552 | for seconds in range(60):
553 | print(hours, ':', minutes, ':', seconds)
554 | >>> 0 : 0 : 0
555 | >>> 0 : 0 : 1
556 | >>> 0 : 0 : 2
557 | ...
558 | >>> 23 : 59 : 58
559 | >>> 23 : 59 : 59
560 | ```
561 | При помощи вложенных циклов можно решать уравнения:
562 | Уравнение 12x+13y=777.
563 | Решение:
564 | ```python
565 | for x in range(777):
566 | for y in range(777):
567 | if 12 * x + 13 * y == 777:
568 | print(x, y)
569 |
570 | ```
571 | # Строки
572 | ## Индексация строк
573 | 
574 | Пример вывода символа из строки:
575 | ```python
576 | s = 'Python'
577 | print(s[1]) # выводит символ с индексом 1 (2 с начала)
578 | print(s[-3]) # выводит символ с индексом -3 (3 с конца)
579 | >>> y
580 | >>> h
581 |
582 | ```
583 | ## Вывод символов строки
584 | Для вывода каждого символа на новой строке используют такую конструкцию:
585 | ```python
586 | s = 'abcdef'
587 | for i in range(len(s)):
588 | print(s[i])
589 | >>> a
590 | >>> b
591 | >>> c
592 | >>> d
593 | >>> e
594 | >>> f
595 |
596 | ```
597 | ## Срезы строк
598 | Срез выводит символы с x по y (правильнее будет сказать с x по y-1)
599 | 
600 | ```python
601 | s = 'abcdefghij'
602 | print(s[2:5])
603 | >>> cde
604 | ```
605 | Также можно опускать параметры в срезах
606 | 
607 | 
608 | ```python
609 | s = 'abcdefghij'
610 | print(s[2:])
611 | print(s[:7])
612 | >>> cdefghij
613 | >>> abcdefg
614 | ```
615 | Также можно указать шаг среза, например, срез `s[1:7:2] `создаст строку bdf состоящую из каждого второго символа (индексы 1, 3, 5)
616 | 
617 | Можно указать отрицательный шаг среза:
618 | | s = 'abcdefghij' | s = 'abcdefghij' | s = 'abcdefghij' |
619 | |---|---|---|
620 | | Программный код | Результат | Пояснение |
621 | | s[2:5] | cde | строка состоящая из символов с индексами 2, 3, 4 |
622 | | s[:5] | abcde | первые пять символов строки |
623 | | s[5:] | fghij | строка состоящая из символов с индексами от 5 до конца |
624 | | s[-2:] | ij | последние два символа строки |
625 | | s[:] | abcdefghij | вся строка целиком |
626 | | s[1:7:2] | bdf | строка, состоящая из каждого второго символа с индексами от 1 до 6 |
627 | | s[::-1] | jihgfedcba | строка в обратном порядке, так как шаг отрицательный |
628 | ```python
629 | s = 'abcdefghij'
630 | print(s[::-1])
631 | >>> jihgfedcba
632 |
633 | ```
634 | Изменение символа строки по индексу
635 | Предположим, у нас есть строка `s = 'abcdefghij' `и мы хотим заменить символ с индексом 4 на 'X'. Можно попытаться написать код:
636 | ```python
637 | s[4] = 'X'
638 | ```
639 | Однако такой код не работает. В Python строки являются неизменяемыми, то есть мы не можем менять их содержимое с помощью индексатора.
640 | Правильный код:
641 | ```python
642 | s = s[:4] + 'X' + s[5:]
643 |
644 | ```
645 | Можно присваивать переменным срезы:
646 | ```python
647 | a = slice(1, -1, 3)
648 | print("ABCDEFGHI"[a])
649 | >>> BEH
650 |
651 | ```
652 | ## Методы строк
653 | Методы к строкам применяются так: строка.метод
654 | - Конвертация регистра
655 | ```python
656 | s = 'foO BaR BAZ quX'
657 |
658 |
659 | print(s.capitalize()) # Первое слово с большой буквы, остальные - с маленькой
660 | >>> Foo bar baz qux
661 |
662 | print(s.swapcase()) # Меняет регистр всех символов на противоположный
663 | >>> FOo bAr baz QUx
664 |
665 | print(s.title()) # Каждое слово начинается с заглавной буквы
666 | >>> Foo Bar Baz Qux
667 |
668 | print(s.lower()) # Все символы приводятся к нижнему регистру
669 | >>> foo bar baz qux
670 |
671 | print(s.upper()) # Все символы приводятся к верхнему регистру
672 | >>> FOO BAR BAZ QUX
673 |
674 |
675 | a = "ßßß"
676 | b = "SSSSSS"
677 | print(a.casefold() == b.casefold()) # Переводит все символы в нижний регистр (Полезно при работе с немецким языком)
678 | >>> True
679 |
680 | ```
681 | - Поиск и замена
682 | ```python
683 | s = 'foo bar foo baz foo qux'
684 |
685 | # Метод count(, , ) - количество вхождений подстроки
686 | print(s.count('foo'))
687 | print(s.count('foo', 0, 10))
688 | >>> 3
689 | >>> 1
690 |
691 | # Метод startswith(, , ) - проверка начала строки
692 | print(s.startswith('foo'))
693 | print(s.startswith('bar'))
694 | >>> True
695 | >>> False
696 |
697 | # Метод endswith(, , ) - проверка конца строки
698 | print(s.endswith('qux'))
699 | print(s.endswith('bar'))
700 | >>> True
701 | >>> False
702 |
703 | # Метод find(, , ) - индекс первого вхождения (или -1)
704 | print(s.find('foo'))
705 | print(s.find('python'))
706 | >>> 0
707 | >>> -1
708 |
709 | # Метод rfind(, , ) - поиск с конца строки
710 | print(s.rfind('foo'))
711 | print(s.rfind('python'))
712 | >>> 16
713 | >>> -1
714 |
715 | # Метод index(, , ) - как find(), но вызывает ошибку при отсутствии
716 | print(s.index('foo'))
717 | # print(s.index('python')) # Вызовет ValueError
718 | >>> 0
719 |
720 | # Метод rindex(, , ) - поиск с конца с ошибкой при отсутствии
721 | print(s.rindex('foo'))
722 | # print(s.rindex('python')) # Вызовет ValueError
723 | >>> 16
724 |
725 | s = ' foo bar foo baz foo qux '
726 |
727 | # Метод strip() - удаляет пробелы с обоих концов
728 | print(s.strip())
729 | >>> foo bar foo baz foo qux
730 |
731 | # Метод lstrip() - удаляет пробелы только слева
732 | print(s.lstrip())
733 | >>> foo bar foo baz foo qux______
734 |
735 | # Метод rstrip() - удаляет пробелы только справа
736 | print(s.rstrip())
737 | >>> ______foo bar foo baz foo qux
738 |
739 | s = '-+-+abc+-+-'
740 |
741 | # Удаление указанных символов с обоих концов
742 | print(s.strip('+-'))
743 | >>> abc
744 |
745 | # Удаление указанных символов справа
746 | print(s.rstrip('+-'))
747 | >>> -+-+abc
748 |
749 | # Удаление указанных символов слева
750 | print(s.lstrip('+-'))
751 | >>> abc+-+-
752 |
753 | # Удаление указанного префикса (суффикса)
754 | print("-+-+abc+-+-".removeprefix("-+"))
755 | >>> -+abc+-+-
756 | print("-+-+abc+-+-".removesuffix("+-"))
757 | >>> -+-+abc+-
758 |
759 | s = 'foo bar foo baz foo qux'
760 |
761 | # Метод replace(, , ) - замена всех вхождений
762 | print(s.replace('foo', 'grault')) # Все вхождения
763 | >>> grault bar grault baz grault qux
764 |
765 | print(s.replace('foo', 'grault', 2)) # Только 2 первых замены
766 | >>> grault bar grault baz foo qux0
767 |
768 | # Разделение на строки
769 | text_with_lot_of_lines = """A
770 | B
771 | C
772 | D
773 | E"""
774 | print(text_with_lot_of_lines.splitlines())
775 | >>> ['A', 'B', 'C', 'D', 'E']
776 |
777 | # Дополнение строку нулями слева, чтобы её общая длина стала равна аргументу
778 | print("234".zfill(12))
779 | >>> 000000000234
780 |
781 | ```
782 | - Классификация символов
783 | ```python
784 | print('Python3'.isalnum()) # состоит ли строка только из букв и/или цифр
785 | >>> True
786 |
787 | print('Hello'.isalpha()) # состоит ли строка только из букв
788 | >>> True
789 |
790 | print('2023'.isdigit()) # состоит ли строка только из цифр
791 | >>> True
792 |
793 | print('python'.islower()) # все ли буквы в строке строчные
794 | >>> True
795 |
796 | print('PYTHON'.isupper()) # все ли буквы в строке заглавные
797 | >>> True
798 |
799 | print(' '.isspace()) # состоит ли строка только из пробелов
800 | >>> True
801 |
802 | ```
803 | ## partition()
804 | Помимо метода `split() `строковый тип данных содержит метод `partition()`. Метод `partition()` принимает на вход один аргумент `sep`, разделяет строку при первом появлении `sep` и возвращает кортеж, состоящий из трех элементов: часть перед разделителем, сам разделитель и часть после разделителя. Если разделитель не найден, то кортеж содержит саму строку, за которой следуют две пустые строки.
805 | ```python
806 | s1 = 'abc-de'.partition('-')
807 | s2 = 'abc-de'.partition('.')
808 | s3 = 'abc-de-fgh'.partition('-')
809 |
810 | print(s1)
811 | print(s2)
812 | print(s3)
813 | >>> ('abc', '-', 'de')
814 | >>> ('abc-de', '', '')
815 | >>> ('abc', '-', 'de-fgh')
816 |
817 | ```
818 | ## format(); format_map()
819 | В Python можно использовать заполнители:
820 | ```python
821 | birth_year = 1992
822 | name = 'Timur'
823 | profession = 'math teacher'
824 | text = 'My name is {}, I was born in {}, I work as a {}.'.format(name, birth_year, profession)
825 |
826 | print(text)
827 | >>> My name is Timur, I was born in 1992, I work as a math teacher.
828 |
829 | ```
830 | Также можно несколько раз использовать один и тот же аргумент:
831 | ```python
832 | name = 'Timur'
833 | city = 'Moscow'
834 | text1 = 'My name is {0}-{0}-{0}!'.format(name, city)
835 | text2 = '{1} is my city and {0} is my name!'.format(name, city)
836 |
837 | print(text1)
838 | >>> My name is Timur-Timur-Timur!
839 |
840 | print(text2)
841 | >>> Moscow is my city and Timur is my name!
842 |
843 | ```
844 | Также существует и функция `format():`
845 | Она применяет к первому аргументу форматирование (второй аргумент):
846 | ```python
847 | print(format(1.23456, ".2f")) # 2 цифры после запятой
848 | >>> 1.23
849 |
850 | ```
851 | Есть и метод `format_map()`:
852 | ```python
853 | print("Привет, {name}".format_map({"name": "Никита"}))
854 | >>> Привет, Никита
855 |
856 | ```
857 | ## f-строки
858 | Строки вида
859 | ```python
860 | name = 'Никита'
861 | print(name, "- мой друг")
862 | >>> Никита - мой друг
863 | ```
864 | Можно изменить на:
865 | ```python
866 | name = 'Никита'
867 | print(f"{name} - мой друг")
868 | >>> Никита - мой друг
869 | ```
870 | В f-строках переменные нужно указывать в {} скобках, а текст просто писать
871 |
872 | ## Строки в памяти компьютера
873 | Таблица ASCII:
874 | 
875 | Функция `ord() `позволяет определить код некоторого символа в таблице символов Unicode.
876 | ```python
877 | num1 = ord('A')
878 | num2 = ord('B')
879 | num3 = ord('a')
880 | print(num1, num2, num3)
881 | >>> 65 66 97
882 | ```
883 | Функция `chr() `позволяет определить по коду символа сам символ. Аргументом данной функции является численный код.
884 | ```python
885 | chr1 = chr(65)
886 | chr2 = chr(75)
887 | chr3 = chr(110)
888 | print(chr1, chr2, chr3)
889 | >>> A K n
890 |
891 | ```
892 | ## Сравнение строк
893 | Строки можно сравнивать, работает это по лексикографическому порядку (точнее, по ASCII)
894 | Строчные символы больше заглавных
895 | ```python
896 | print('d' > 'D')
897 | print('Ы' < 'ы')
898 | >>> True
899 | >>> True
900 |
901 | ```
902 | # Списки
903 | ## Создание списка
904 | Списки могут содержать разные типы данных
905 | Список можно задать двумя способами:
906 | ```python
907 | a = []
908 | a = list()
909 |
910 | ```
911 | ## Основы (len, sum, min, max, in)
912 | ```python
913 | a = [1, 5, 3]
914 |
915 | print(len(a)) # длина списка (количество элементов)
916 | >>> 3
917 |
918 | print(sum(a)) # сумма элементов списка
919 | >>> 9
920 |
921 | print(min(a)) # минимум из списка
922 | >>> 1
923 |
924 | print(max(a)) # максимум из списка
925 | >>> 5
926 |
927 | print(1 in a) # есть ли элемент со значением 1 в списке a
928 | >>> True
929 |
930 | ```
931 | В списках индексация, срезы, конкатенация и умножение аналогично строкам, только тут вместо символов строки элементы списка.
932 |
933 | Отличие списков от строк:
934 | Несмотря на всю схожесть списков и строк, есть одно очень важное отличие: строки — неизменяемые объекты, а списки – изменяемые.
935 |
936 | Список можно удобно заполнить порядковыми числами:
937 | ```python
938 | a = list(range(1, 10, 2))
939 | print(a)
940 | >>> [1, 3, 5, 7, 9]
941 |
942 | ```
943 | ## Добавление элементов
944 | `a.append()` - добавление элемента в конец списка
945 | ```python
946 | a = [1, 1, 2, 3, 5, 8, 13]
947 | a.append(21) # добавляем число 21 в конец списка
948 | a.append(34) # добавляем число 34 в конец списка
949 | print(a)
950 | >>> [1, 1, 2, 3, 5, 8, 13, 21, 34]
951 |
952 | ```
953 | ## Объединение списков
954 | Чтобы объединить списки нужно использовать следующий метод:
955 | ```python
956 | a = [1, 2]
957 | b = [5, 7]
958 | a.extend(b)
959 | print(a)
960 | >>> [1, 2, 5, 7]
961 |
962 | ```
963 | ## Удаление элементов
964 | Для удаления элементов используется инструкция `del`
965 | Эту инструкцию можно использовать и для удаления переменных
966 | ```python
967 | a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
968 | del a[5] # удаляем элемент, имеющий индекс 5
969 | print(a)
970 | >>> [1, 2, 3, 4, 5, 7, 8, 9]
971 |
972 | ```
973 | ## Вывод элементов списка
974 | - Вывод через цикл
975 | ```python
976 | a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
977 | for i in range(len(a)):
978 | print(a[i])
979 | >>> 0
980 | >>> 1
981 | >>> 2
982 | >>> 3
983 | >>> 4
984 | >>> 5
985 | >>> 6
986 | >>> 7
987 | >>> 8
988 | >>> 9
989 | >>> 10
990 |
991 | ```
992 | - Распаковка списка
993 | ```python
994 | a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
995 | print(*a)
996 | >>> 0 1 2 3 4 5 6 7 8 9 10
997 |
998 | ```
999 | - Распаковка списка и вывод каждого элемента на новой строке
1000 | ```python
1001 | a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1002 | print(*a, sep="\n")
1003 | >>> 0
1004 | >>> 1
1005 | >>> 2
1006 | >>> 3
1007 | >>> 4
1008 | >>> 5
1009 | >>> 6
1010 | >>> 7
1011 | >>> 8
1012 | >>> 9
1013 | >>> 10
1014 |
1015 | ```
1016 | ## split(), join()
1017 | Метод `split()` разбивает строку на слова, используя в качестве разделителя последовательность пробельных символов, и возвращает список из этих слов.
1018 | ```python
1019 | s = 'Python is the most powerful language'
1020 | words = s.split()
1021 | print(words)
1022 | >>> ['Python', 'is', 'the', 'most', 'powerful', 'language']
1023 | ```
1024 | Также можно указать аргумент, который будет разделителем:
1025 | ```python
1026 | ip = '192.168.1.24'
1027 | numbers = ip.split('.') # указываем явно разделитель
1028 | print(numbers)
1029 | >>> ['192', '168', '1', '24']
1030 |
1031 | ```
1032 | Метод `join()` собирает строку из элементов списка, используя в качестве разделителя строку, к которой применяется метод.
1033 | ```python
1034 | words = ['Python', 'is', 'the', 'most', 'powerful', 'language']
1035 | s = ' '.join(words)
1036 | print(s)
1037 | >>> Python is the most powerful language
1038 |
1039 | ```
1040 | Шпаргалки:
1041 | 
1042 | 
1043 | 
1044 |
1045 | ## Методы списков
1046 | ```python
1047 | s = [1, 3, 5]
1048 | s.insert(4, 2) # вставляет 2 в индекс 4
1049 | print(s)
1050 | >>> [1, 3, 5, 2]
1051 |
1052 | s = [1, 3, 5]
1053 | print(s.index(3)) # выводит индекс первого вхождения 3 список s
1054 | >>> 1
1055 |
1056 | s = [1, 3, 5]
1057 | s.remove(3) # удаляет первое вхождение элемента 3
1058 | print(s)
1059 | >>> [1, 5]
1060 |
1061 | s = [1, 3, 5]
1062 | s.pop(2) # удаляет элемент с индексом 2
1063 | print(s)
1064 | >>> [1, 3]
1065 |
1066 | s = [1, 3, 3, 3, 3, 5]
1067 | print(s.count(3)) # выводит количество элементов со значением 3
1068 | >>> 4
1069 |
1070 | s = [1, 3, 5]
1071 | s.reverse() # переворачивает список
1072 | print(s)
1073 | >>> [5, 3, 1]
1074 |
1075 | s = [1, 3, 5]
1076 | s.clear() # очищает список
1077 | print(s)
1078 | >>> []
1079 |
1080 | s = [1, 3, 5]
1081 | g = s.copy() # делает копия списка, при изменении оригинала копия тоже изменяется
1082 | print(g)
1083 | >>> [1, 3, 5]
1084 |
1085 | ```
1086 | ## Сортировка списков
1087 | В Python списки имеют встроенный метод `sort()`, который сортирует элементы списка по возрастанию или убыванию.
1088 | ```python
1089 | a = [1, 7, -3, 9, 0, -67, 34, 12, 45, 1000, 6, 8, -2, 99]
1090 | a.sort()
1091 | print('Отсортированный список:', a)
1092 | >>> Отсортированный список: [-67, -3, -2, 0, 1, 6, 7, 8, 9, 12, 34, 45, 99, 1000]
1093 | ```
1094 | Также можно сортировать по убыванию. Если требуется отсортировать список по убыванию, необходимо явно указать параметр `reverse = True.`
1095 | ```python
1096 | a = [1, 7, -3, 9, 0, -67, 34, 12, 45, 1000, 6, 8, -2, 99]
1097 | a.sort(reverse=True) # сортируем по убыванию
1098 | print('Отсортированный список:', a)
1099 | >>> Отсортированный список: [1000, 99, 45, 34, 12, 9, 8, 7, 6, 1, 0, -2, -3, -67]
1100 | ```
1101 | Функция `sorted() `возвращает отсортированный список, не изменяя оригинальный.
1102 | ```python
1103 | a = [1, 5, 3]
1104 | print(sorted(a))
1105 | >>> [1, 3, 5]
1106 | ```
1107 | ## Генераторы списков; списочные выражения
1108 | ```python
1109 | numbers = [i for i in range(10)] # числа от 0 до 9
1110 | print(numbers)
1111 | >>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1112 |
1113 | numbers = [i**2 for i in range(10)] # квадраты чисел от 0 до 9
1114 | print(numbers)
1115 | >>> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
1116 |
1117 | numbers = [int(input()) for i in range(int(input()))] # ввод n чисел с клавиатуры
1118 | print(numbers)
1119 | <<< 5
1120 | <<< 1
1121 | <<< 2
1122 | <<< 3
1123 | <<< 4
1124 | <<< 5
1125 | >>> [1, 2, 3, 4, 5]
1126 |
1127 | numbers = [i * j for i in range(1, 5) for j in range(2)] # вложенные циклы
1128 | print(numbers)
1129 | >>> [0, 1, 0, 2, 0, 3, 0, 4]
1130 |
1131 | numbers = [i for i in range(21) if i % 2 == 0] # четные числа от 0 до 20 (условие в списочном выражении)
1132 | print(numbers)
1133 | >>> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
1134 | ```
1135 | В списочных выражениях нельзя использовать `else` и несколько условий.
1136 |
1137 | ## Нахождение чисел палиндромов
1138 | Во-первых, вот что такое палиндром:
1139 | Числа-палиндромы — числа, которые в определённой позиционной системе исчисления (как правило — в десятичной) читаются одинаково как справа налево, так и слева направо.
1140 | Достаточно просто доказать, что чисел-палиндромов бесконечно много. Одним из способов доказательства является замена любой выбранной цифры в их написании двумя любыми другими цифрами, в результате чего получается новое число-палиндром.
1141 | ```python
1142 | palindromes = [i for i in range(100, 1001) if i == int(str(i)[::-1])]
1143 | print(palindromes)
1144 |
1145 | ```
1146 | ## Методы сортировки списков
1147 | - Сортировка пузырьком
1148 | Алгоритм сортировки пузырьком состоит из повторяющихся проходов по сортируемому списку. За каждый проход элементы последовательно сравниваются попарно и, если порядок в паре неверный, выполняется обмен элементов. Проходы по списку повторяются n−1 раз, где n – длина списка. При каждом проходе алгоритма по внутреннему циклу, очередной наибольший элемент списка ставится на свое место в конце списка рядом с предыдущим «наибольшим элементом».
1149 | Наибольший элемент каждый раз «всплывает» до нужной позиции, как пузырёк в воде — отсюда и название алгоритма.
1150 |
1151 | Алгоритм пузырьковой сортировки считается учебным и практически не применяется вне учебной литературы, а на практике применяются более эффективные.
1152 |
1153 | Реализация:
1154 | ```python
1155 | a = [1, 7, -3, 9, 0, -67, 34, 12, 45, 1000, 6, 8, -2, 99]
1156 | n = len(a)
1157 |
1158 | for i in range(n - 1):
1159 | for j in range(n - 1 - i):
1160 | if a[j] > a[j + 1]: # если порядок элементов пары неправильный
1161 | a[j], a[j + 1] = a[j + 1], a[j] # меняем элементы пары местами
1162 |
1163 | print('Отсортированный список:', a)
1164 |
1165 | ```
1166 | - Сортировка выбором
1167 | Сортировка выбором улучшает пузырьковую сортировку, совершая всего один обмен за каждый проход по списку. Для этого алгоритм ищет максимальный элемент и помещает его на соответствующую позицию. Как и для пузырьковой сортировки, после первого прохода самый большой элемент находится на правильном месте. После второго прохода на своё место становится следующий максимальный элемент. Проходы по списку повторяются n−1 раз, где n – длина списка, поскольку последний из них автоматически оказывается на своем месте.
1168 |
1169 | Алгоритм сортировки выбором также считается учебным и практически не применяется вне учебной литературы. На практике используют более эффективные алгоритмы.
1170 |
1171 | Реализация:
1172 | ```python
1173 | a = [78, -32, 5, 39, 58, -5, -63, 57, 72, 9, 53, -1, 63, -97, -21, -94, -47, 57, -8, 60, -23, -72, -22, -79, 90, 96, -41, -71, -48, 84, 89, -96, 41, -16, 94, -60, -64, -39, 60, -14, -62, -19, -3, 32, 98, 14, 43, 3, -56, 71, -71, -67, 80, 27, 92, 92, -64, 0, -77, 2, -26, 41, 3, -31, 48, 39, 20, -30, 35, 32, -58, 2, 63, 64, 66, 62, 82, -62, 9, -52, 35, -61, 87, 78, 93, -42, 87, -72, -10, -36, 61, -16, 59, 59, 22, -24, -67, 76, -94, 59]
1174 |
1175 | n = len(a)
1176 |
1177 | for i in range(n):
1178 | mx = max(a[:n - i])
1179 | mx_ind = a.index(mx)
1180 |
1181 | a[n - 1 - i], a[mx_ind] = a[mx_ind], a[n - 1 - i]
1182 |
1183 | print('Отсортированный список:', a)
1184 |
1185 | ```
1186 | - Сортировка простыми вставками
1187 | Алгоритм сортировки простыми вставками делит список на 2 части — отсортированную и неотсортированную. Из неотсортированной части извлекается очередной элемент и вставляется на нужную позицию в отсортированной части, в результате чего отсортированная часть списка увеличивается, а неотсортированная уменьшается. Так происходит, пока не исчерпан набор входных данных и не отсортированы все элементы.
1188 |
1189 | Сортировка простыми вставками наиболее эффективна, когда список уже частично отсортирован и элементов массива немного. Если элементов в списке меньше 10, то этот алгоритм - один из самых быстрых.
1190 |
1191 | Реализация:
1192 | ```python
1193 | a = [1, 7, -3, 9, 0, -67, 34, 12, 45, 1000, 6, 8, -2, 99]
1194 | n = len(a)
1195 |
1196 | for i in range(1, n):
1197 | elem = a[i] # берем первый элемент из неотсортированной части списка
1198 | j = i
1199 |
1200 | # пока элемент слева существует и больше нашего текущего элемента
1201 | while j >= 1 and a[j - 1] > elem:
1202 | # смещаем j-1-й элемент отсортированной части вправо
1203 | a[j] = a[j - 1]
1204 | # сами идём влево, дальше ищем место для нашего текущего элемента
1205 | j -= 1
1206 |
1207 | # нашли место для нащего текущего элемента из неотсортированной части
1208 | # и вставляем его на индекс j в отсортированной части
1209 | a[j] = elem
1210 |
1211 | print('Отсортированный список:', a)
1212 |
1213 |
1214 | ```
1215 | # Тип данных bool и NoneType
1216 | ## bool
1217 | - bool может иметь значение `True `или `False`.
1218 | - `a and b `дает `True`, если оба операнда `True`, или `False`, если хотя бы один из них `False`
1219 | - `a or b `дает `False`, если оба операнда `False`, или `True`, если хотя бы один из них `Truef`
1220 | - `not a` дает `True`, если `a` имеет значение `False`, или `False`, если `a` имеет значение `True`.
1221 |
1222 | ```python
1223 | print(True == 1)
1224 | print(False == 0)
1225 | >>> True
1226 | >>> True
1227 |
1228 | print(True == 1)
1229 | print(False == 0)
1230 | >>> True
1231 | >>> True
1232 | ```
1233 | Для приведения других типов данных к булеву существует функция `bool()`, работающая по следующим соглашениям:
1234 | - строки: пустая строка – ложь (`False`), непустая строка – истина (`True`)
1235 | - числа: нулевое число – ложь (`False`), ненулевое число (в том числе и меньшее нуля) – истина (`True`)
1236 | - списки: пустой список – ложь (`False`), непустой – истина (`True`).
1237 |
1238 | В языке Python имеется встроенная функция `isinstance()` для проверки соответствия типа объекта какому-либо типу данных.
1239 | ```python
1240 | print(isinstance(3, int))
1241 | print(isinstance(3.5, float))
1242 | print(isinstance('Beegeek', str))
1243 | print(isinstance([1, 2, 3], list))
1244 | print(isinstance(True, bool))
1245 | >>> True
1246 | >>> True
1247 | >>> True
1248 | >>> True
1249 | >>> True
1250 |
1251 | ```
1252 | В языке Python имеется встроенная функция `type()`, позволяющая получить тип указанного в качестве аргумента объекта.
1253 | ```python
1254 | print(type(3))
1255 | print(type(3.5))
1256 | print(type('Beegeek'))
1257 | print(type([1, 2, 3]))
1258 | print(type(True))
1259 | >>>
1260 | >>>
1261 | >>>
1262 | >>>
1263 | >>>
1264 |
1265 | ```
1266 | ## NoneType
1267 | ```python
1268 | var = None
1269 | print(type(var))
1270 | >>>
1271 | ```
1272 | Сравнение `None` с любым объектом, отличным от `None`, дает значение `False`. `None` возвращается если функция ничего не вернула. Рекомендуется сравнивать `None` через `is`:
1273 | ```python
1274 | a = None
1275 | print(a is None)
1276 | >>> True
1277 |
1278 | ```
1279 | # Вложенные списки
1280 | ## Основы
1281 | Создание вложенного списка:
1282 | ```python
1283 | my_list = [[0], [1, 2], [3, 4, 5]]
1284 | ```
1285 | Чтобы получить число 2 мы используем такую команду:
1286 | ```python
1287 | my_list = [[0], [1, 2], [3, 4, 5]]
1288 | print(my_list[1][1]) # сначала получаем список с индексом 1 ([1, 2]), а затем первый индекс (2)
1289 | >>> 2
1290 |
1291 | ```
1292 | Функции `min()` и `max() `могут работать и со списками. Если этим функциям передается несколько списков, то целиком возвращается один из переданных списков. При этом сравнение происходит поэлементно: сначала сравниваются первые элементы списков. Если они не равны, то функция `min()` вернет тот список, первый элемент которого меньше, `max()` – наоборот. Если первые элементы равны, то будут сравниваться вторые и т. д.
1293 | Пример:
1294 | Задача:
1295 | На вход программе подается число n. Напишите программу, которая создает и выводит построчно вложенный список, состоящий из n списков [[1], [1, 2], [1, 2, 3], ..., [1, 2, ..., n]].
1296 | Формат входных данных
1297 | На вход программе подается натуральное число n.
1298 | Формат выходных данных
1299 | Программа должна вывести построчно указанный вложенный список.
1300 | Решение:
1301 | ```python
1302 | print(*[[i for i in range(1, j+1)] for j in range(1, int(input())+1)], sep="\n")
1303 |
1304 | ```
1305 | ## Матрицы, ljust(), rjust()
1306 | Матрицы - прямоугольные таблицы, заполненные какими-то значениями, обычно числами.
1307 | 
1308 |
1309 | Перебор элементов матрицы:
1310 | ```python
1311 | rows, cols = 3, 4 # rows - количество строк, cols - количество столбцов
1312 |
1313 | matrix = [[2, 3, 1, 0],
1314 | [9, 4, 6, 8],
1315 | [4, 7, 2, 7]]
1316 |
1317 | for r in range(rows):
1318 | for c in range(cols):
1319 | print(matrix[r][c], end=' ')
1320 | print()
1321 | >>> 2 3 1 0
1322 | >>> 9 4 6 8
1323 | >>> 4 7 2 7
1324 | ```
1325 | Строковый метод `ljust(arg) `выравнивает текст по ширине, добавляя пробелы в конец текста:
1326 | Строковый метод `rjust(arg)` выравнивает текст по ширине, добавляя пробелы в начало текста:
1327 | ```python
1328 | matrix = [[1, 2, 3],
1329 | [4, 590, 6],
1330 | [70, 8, 9]]
1331 |
1332 | for i in range(3):
1333 | for j in range(3):
1334 | print(str(matrix[i][j]).ljust(5), end="")
1335 | print()
1336 |
1337 | print()
1338 |
1339 | for i in range(3):
1340 | for j in range(3):
1341 | print(str(matrix[i][j]).rjust(5), end="")
1342 | print()
1343 | >>> 1 2 3
1344 | >>> 4 590 6
1345 | >>> 70 8 9
1346 |
1347 | >>> 1 2 3
1348 | >>> 4 590 6
1349 | >>> 70 8 9
1350 |
1351 | ```
1352 | Таблица умножения n на m:
1353 | ```python
1354 | n, m = int(input()), int(input())
1355 | s = [[i * j for i in range(m)] for j in range(n)]
1356 | for i in s:
1357 | print(*i)
1358 | <<< 4
1359 | <<< 6
1360 | >>> 0 0 0 0 0 0
1361 | >>> 0 1 2 3 4 5
1362 | >>> 0 2 4 6 8 10
1363 | >>> 0 3 6 9 12 15
1364 |
1365 | ```
1366 | # Кортежи
1367 | ## Введение
1368 | Кортежи по своей природе (задумке) – неизменяемые аналоги списков. Кортеж описывается следующим образом:
1369 | ```python
1370 | list = [] # список
1371 | tuple = () # кортеж
1372 | ```
1373 | Для создания кортежа с единственным элементом после значения элемента ставят замыкающую запятую:
1374 | ```python
1375 | my_tuple = (1,)
1376 | print(type(my_tuple))
1377 | >>>
1378 | ```
1379 | Если её не поставить, то будет создан не кортеж, а просто переменная со значением 1 (типа `int`)
1380 |
1381 | В чём кортеж превосходит список?
1382 | - Скорость
1383 | - Безопасность
1384 | Где встречаются кортежи? Если функция возвращает несколько значений, она возвращает кортеж.
1385 |
1386 | Важно! Тот факт, что кортеж является неизменяемым вовсе не означает, что мы не можем поменять содержимое списка в кортеже.
1387 |
1388 | ## Основы
1389 | Кортеж можно превратить в список используя функцию `list(mytuple)`.
1390 | Список можно превратить в кортеж используя функцию `tuple(mylist)`.
1391 | Кортеж можно преобразовать в строку с помощью строкового метода `join(mytuple)`.
1392 | Строку можно преобразовать в кортеж с помощью функции `tuple(mystring)`.
1393 |
1394 | Кортежи поддерживают:
1395 | - доступ к элементу по индексу (только для получения значений элементов)
1396 | - методы, в частности `index()`, `count()`
1397 | - встроенные функции, в частности `len(), sum(), min(), max()`
1398 | - срезы
1399 | - оператор принадлежности `in`
1400 | - операторы конкатенации (+) и повторения (*).
1401 | Кортежи могут иметь вложенные кортежи и вложенные списки.
1402 |
1403 | ## Сравнение кортежей
1404 | ```python
1405 | print((1, 8) == (1, 8))
1406 | print((1, 8) != (1, 10))
1407 | print((1, 9) < (1, 2))
1408 | print((2, 5) < (6,))
1409 | print(('a', 'bc') > ('a', 'de'))
1410 |
1411 | >>> True
1412 | >>> True
1413 | >>> False
1414 | >>> True
1415 | >>> False
1416 | ```
1417 | Обратите внимание: операции == и != применимы к любым кортежам, независимо от типов элементов. А вот операции <, >, <=, >= применимы только в том случае, когда соответствующие элементы кортежей имеют один тип.
1418 |
1419 | ## Сортировка кортежей
1420 | Так как кортежи неизменяемы, то и метода `sort()` у них нет. Но кортеж можно отсортировать при помощи функции `sorted()`. Данная функция возвращает отсортированный кортеж/список, а не сортирует его «на месте».
1421 | Примеры решения задач:
1422 | Условие: Напишите программу, которая выводит список хорошистов и отличников в классе.
1423 | Формат входных данных
1424 | На вход программе подается натуральное число
1425 | n, далее следует n строк с фамилией школьника и его оценкой на каждой из них.
1426 | Формат выходных данных
1427 | Программа должна вывести сначала все введённые строки с фамилиями и оценками учеников в том же порядке. Затем следует пустая строка, а затем выводятся строки с фамилиями и оценками хорошистов и отличников (в том же порядке).
1428 | Решение:
1429 | ```python
1430 | a = [tuple(input().split()) for _ in range(int(input()))] # создаем n кортежей, которые будут иметь 2 значения - фамилия и оценка
1431 | for i in a:
1432 | print(*i)
1433 |
1434 | print()
1435 |
1436 | for name, grade in a: # перебираем каждый кортеж
1437 | if int(grade) > 3: # если оценка выше 3, выводим имя и оценку
1438 | print(name, grade)
1439 |
1440 | ```
1441 | ## Распаковка кортежей; “хвосты”
1442 | Кортежи можно распаковывать так:
1443 | ```python
1444 | print(*tuple)
1445 | ```
1446 | Но мы также можем присвоить переменным значения элементов кортежа:
1447 | ```python
1448 | colors = ('red', 'green', 'blue', 'cyan')
1449 |
1450 | (a, b, c, d) = colors
1451 |
1452 | print(a)
1453 | print(b)
1454 | print(c)
1455 | print(d)
1456 | >>> red
1457 | >>> green
1458 | >>> blue
1459 | >>> cyan
1460 | ```
1461 | При этом переменных должно быть ровно столько, сколько символов в кортеже.
1462 | Но что делать если нам нужны например только первые 2 переменные из кортежа/списка? Для этого используют такую конструкцию:
1463 | ```python
1464 | *names, surname = ('Стефани', 'Джоанн', 'Анджелина', 'Джерманотта')
1465 |
1466 | print(names)
1467 | print(surname)
1468 | >>> ['Стефани', 'Джоанн', 'Анджелина']
1469 | >>> Джерманотта
1470 | ```
1471 | Перед `names` мы поставили `*`, это означает что это список, который примет все значения, которые не приняли другие переменные.
1472 | Учтите, что `*tail` всегда будет списком, даже когда в него попадает лишь один элемент или даже ноль.
1473 |
1474 | # Множества
1475 | ## Множества в математике
1476 | В математике множество – совокупность объектов, понимаемых как единое целое. Обычно множества обозначают большими латинскими буквами.
1477 | Если два множества X и Y состоят из одних и тех же элементов, то они называются равными X=Y. Обратите внимание, порядок расположения элементов в записи множеств при их сравнении во внимание не принимается.
1478 | Если все элементы множества X принадлежат также и множеству Y, то говорят, что X является подмножеством Y, а записывается это так: X ⊂ Y.
1479 | Если множество X конечно, то через ∣X∣ обозначается количество элементов множества X.
1480 | Множество X, содержащее n элементов, имеет 2^n подмножеств, включая пустое. Например, X = {a, b, c} (3 элемента) имеет 8 подмножеств: ∅, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}.
1481 | Важно! Множества – неупорядоченные совокупности, то есть неважно, в каком порядке указаны элементы множества.
1482 |
1483 | ## Пустое множество
1484 | Пустое множество – множество, не содержащего ни одного элемента. Оно обозначается знаком ∅.
1485 |
1486 | ## Числовые множества
1487 | - Натуральные числа:
1488 | N={1,2,3,4,5,…}
1489 | - Целые числа:
1490 | Z={0,±1,±2,±3,±4,±5,…}
1491 | - Рациональные числа. Рациональным числом в математике называется любое число, представимое в виде частного двух целых чисел с отличным от нуля знаменателем. Множество рациональных чисел обозначается буквой Q и содержит следующие числа:
1492 | Q={, m∈Z, n∈N}.
1493 | - Иррациональные числа. Не все числа в математике можно представить в виде рационального числа. Примером служат числа:
1494 | ≈1.414213562…
1495 | π≈3.1415926535…
1496 | e≈2.71828182845…
1497 | Такие числа называются иррациональными и являются бесконечными непериодическими дробями. Иными словами, в «бесконечных хвостах» иррациональных чисел нет никакой закономерности. Иррациональные числа часто обозначают буквой I.
1498 | - Вещественные числа:
1499 | Объединение рациональных и иррациональных чисел образует множество вещественных чисел. Множество вещественных чисел R определяется так: R=Q∪I. Символ ∪ – означает объединение множеств.
1500 | - Комплексные числа:
1501 | Комплексные числа — это числа вида a + bi, где a и b — действительные числа, а i — мнимая единица (i^2 = −1).
1502 | Это множество обозначают буквой C.
1503 |
1504 | ## Операции над множествами
1505 | - Объединение множеств – множество, состоящее из элементов, принадлежащих хотя бы одному из объединяемых множеств. Для объединения множеств используется символ ∪.
1506 | 
1507 |
1508 | - Пересечение множеств – множество, состоящее из элементов, принадлежащих одновременно каждому из пересекающихся множеств. Для пересечения множеств используется символ ∩.
1509 | 
1510 |
1511 | - Разность множеств – множество, в которое входят только элементы первого множества, не входящие во второе множество. Для разности множеств используется символ ∖.
1512 | 
1513 |
1514 | - Симметрическая разность множеств – множество, включающее все элементы исходных множеств, не принадлежащие одновременно обоим исходным множествам. Для симметрической разности множеств используется символ △.
1515 | 
1516 |
1517 | - Дополнение множества – множество всех элементов, в нем не содержащихся. Для операции дополнения множества используется символ ¬.
1518 | 
1519 |
1520 | ## Диаграммы Эйлера-Венна при решении задач
1521 | Задача. Каждый ученик онлайн-школы BEEGEEK изучает или математику или информатику, или и то и другое одновременно. Всего 75 учеников изучает математику, а 27 – информатику и только 13 – оба предмета. Сколько учеников учится в онлайн-школе BEEGEEK?
1522 | Решение. Введем обозначения: множество учеников, изучающих математику – М, информатику – И. Изображаем множества на диаграмме Эйлера-Венна в наиболее общем случае.
1523 | 
1524 | Рассуждаем следующим образом: оба предмета изучают 13 учеников. Значит, только математику изучают 75 − 13 = 62 ученика, только информатику изучают 27 − 13 = 14 учеников. Таким образом, всего в школе учится 62 + 13 + 14 = 89 учеников. Ответ: 89.
1525 |
1526 | ## Введение в множества в Python
1527 | Важно знать:
1528 | - все элементы множества различны (уникальны), два элемента не могут иметь одинаковое значение
1529 | - множества неупорядочены, то есть элементы не хранятся в каком-то определенном порядке
1530 | - элементы множества должны относиться к неизменяемым типам данных
1531 | - хранящиеся в множестве элементы могут иметь разные типы данных.
1532 | - Множества изменяемы
1533 | Множество не может содержать список, множество, однако может содержать кортеж.
1534 |
1535 | ## Создание множества
1536 | Чтобы создать множество, нужно перечислить его элементы через запятую в фигурных скобках:
1537 | ```python
1538 | numbers = {2, 4, 6, 8, 10}
1539 | languages = {"Python", "C#", "C++", "Java"}
1540 | favorites = {"Nikita", 144, "My friend"}
1541 |
1542 | ```
1543 | Создать пустое множество можно с помощью встроенной функции, которая называется `set()`:
1544 | ```python
1545 | myset = set() # пустое множество
1546 | ```
1547 | Важно! Создать пустое множество с помощью пустых фигурных скобок нельзя:
1548 | ```python
1549 | myset = {} # создается словарь
1550 |
1551 | ```
1552 | ## Вывод множества
1553 | Вывести множество можно через `print(myset)`.
1554 | Обратите внимание: при выводе множества порядок элементов может отличаться от существовавшего при его создании, поскольку множества — неупорядоченные коллекции данных.
1555 |
1556 | ## set()
1557 | Встроенная функция `set() `помимо создания пустого множества может преобразовывать некоторые типы объектов в множества. В функцию `set() `можно передать один аргумент. Передаваемый аргумент должен быть итерируемым объектом, таким как список, кортеж или строковое значение. Отдельные элементы объекта, передаваемого в качестве аргумента, становятся элементами множества:
1558 | ```python
1559 | myset1 = set(range(10)) # множество из элементов последовательности
1560 | myset2 = set([1, 2, 3, 4, 5]) # множество из элементов списка
1561 | myset3 = set('abcd') # множество из элементов строки
1562 | myset4 = set((10, 20, 30, 40)) # множество из элементов кортежа
1563 | ```
1564 | Пустое множество также можно создать передав функции `set() `в качестве аргумента пустой список, строку или кортеж:
1565 | ```python
1566 | emptyset1 = set([]) # пустое множество из пустого списка
1567 | emptyset2 = set('') # пустое множество из пустой строки
1568 | emptyset3 = set(()) # пустое множество из пустого кортежа
1569 |
1570 | ```
1571 | Множества не могут содержать повторяющиеся элементы. Если в функцию `set()` передать аргумент, содержащий повторяющиеся элементы, то в множестве появится только один из этих повторяющихся элементов.
1572 | ```python
1573 | myset1 = {2, 2, 4, 6, 6}
1574 | myset2 = set([1, 2, 2, 3, 3])
1575 | myset3 = set("aaaaabbbbccccddd")
1576 |
1577 | print(myset1)
1578 | print(myset2)
1579 | print(myset3)
1580 | >>> {2, 4, 6}
1581 | >>> {1, 2, 3}
1582 | >>> {"b", "c", "d", "a"}
1583 |
1584 | ```
1585 | Если требуется создать множество, в котором каждый элемент — строковое значение, содержащее более одного символа, то используем код:
1586 | ```python
1587 | myset = set(['aaa', 'bbbb', 'cc'])
1588 |
1589 | print(myset)
1590 | >>> {'bbbb', 'aaa', 'cc'}
1591 | ```
1592 | Однако вот что будет, если аргумент будет строкой:
1593 | ```python
1594 | myset = set('aaa bbbb cc')
1595 |
1596 | print(myset)
1597 | >>> {' ', 'c', 'a', 'b'}
1598 |
1599 | ```
1600 | ## Основы работы с множествами
1601 | - Функция `len() `возвращает длину множества (количество элементов).
1602 | - Оператор `in `позволяет проверить, содержит ли множество некоторый элемент. В множествах он работает намного быстрее чем в списках.
1603 | - Встроенная функция `sum()` принимает в качестве аргумента множество чисел и вычисляет сумму его элементов.
1604 | - Встроенные функции `min() `и `max()` принимают в качестве аргумента множество и находят минимальный и максимальный элементы соответственно.
1605 | Важно! Индексация и срезы недоступны для множеств. Операция конкатенации + и умножения на число * тоже недоступны для множеств.
1606 |
1607 | ## Перебор элементов множества и распаковка
1608 | Перебор элементов множества осуществляется точно так же, как и перебор элементов списка, то есть с помощью цикла `for`.
1609 | Для вывода элементов множества каждого на отдельной строке можно использовать следующий код:
1610 | ```python
1611 | numbers = {0, 1, 1, 2, 3, 3, 3, 5, 6, 7, 7}
1612 |
1613 | for num in numbers:
1614 | print(num)
1615 | >>> 0
1616 | >>> 1
1617 | >>> 2
1618 | >>> 3
1619 | >>> 5
1620 | >>> 6
1621 | >>> 7
1622 | ```
1623 | Но также можно распаковать таким способом:
1624 | ```python
1625 | numbers = {0, 1, 1, 2, 3, 3, 3, 5, 6, 7, 7}
1626 |
1627 | print(*numbers)
1628 | >>> 0 1 2 3 5 6 7
1629 | ```
1630 | Помните, что множества - неупорядоченные коллекции, а значит если вам нужно вывести элементы по возрастанию, используйте функцию `sorted()`, которая вернёт отсортированный список. Метода `sort()` у множеств нет. В функции можно указать необязательный параметр `reverse`. При `reverse=True` множество будет отсортировано по убыванию.
1631 |
1632 | ## Сравнение множеств
1633 | Множества можно сравнивать между собой. Равные множества имеют одинаковую длину и содержат равные элементы. Для сравнения множеств используются операторы == и !=. Других операторов сравнения у множеств нет.
1634 |
1635 | ## Методы множеств
1636 | Основные:
1637 | - Для добавления нового элемента в множество используется метод `add()`.
1638 | ```python
1639 | numbers = {1, 1, 2, 3, 5, 8, 3} # создаем множество
1640 | numbers.add(21) # добавляем число 21 в множество
1641 | numbers.add(34) # добавляем число 34 в множество
1642 | print(numbers)
1643 | >>> {1, 2, 3, 34, 5, 8, 21}
1644 | ```
1645 | - Метод `remove()` удаляет элемент из множества с генерацией исключения (ошибки) в случае, если такого элемента нет.
1646 | ```python
1647 | numbers = {1, 2, 3, 4, 5}
1648 | numbers.remove(3)
1649 | print(numbers)
1650 | >>> {1, 2, 4, 5}
1651 | ```
1652 | - Метод `discard()` удаляет элемент из множества без генерации исключения (ошибки), если элемент отсутствует.
1653 | ```python
1654 | numbers = {1, 2, 3, 4, 5}
1655 | numbers.discard(3)
1656 | print(numbers)
1657 | >>> {1, 2, 4, 5}
1658 |
1659 | numbers = {1, 2, 3, 4, 5}
1660 | numbers.discard(10)
1661 | print(numbers)
1662 | >>> {1, 2, 3, 4, 5}
1663 | ```
1664 | - Метод `pop()` удаляет и возвращает первый элемент из множества с генерацией исключения (ошибки) при попытке удаления из пустого множества. Аргументы указать нельзя.
1665 | ```python
1666 | numbers = {1, 2, 3, 4, 5}
1667 | print('до удаления:', numbers)
1668 | num = numbers.pop() # удаляет первый элемент множества, возвращая его
1669 | print('удалённый элемент:', num)
1670 | print('после удаления:', numbers)
1671 | >>> до удаления: {1, 2, 3, 4, 5}
1672 | >>> удалённый элемент: 1
1673 | >>> после удаления: {2, 3, 4, 5}
1674 | ```
1675 | - Метод `clear()` удаляет все элементы из множества.
1676 | ```python
1677 | numbers = {1, 2, 3, 4, 5}
1678 | numbers.clear()
1679 | print(numbers)
1680 | >>> set()
1681 |
1682 | ```
1683 | Операции над множествами:
1684 | - Объединение множеств: `union() `возвращает новое множество со всеми элементами первого и второго.
1685 | Для объединения двух множеств можно также использовать оператор |.
1686 | Для изменения текущего множества используется метод `update()`.
1687 | Первый вариант:
1688 | ```python
1689 | myset1 = {1, 2, 3, 4, 5}
1690 | myset2 = {3, 4, 6, 7, 8}
1691 | myset3 = myset1.union(myset2)
1692 | print(myset3)
1693 | >>> {1, 2, 3, 4, 5, 6, 7, 8}
1694 | ```
1695 | Второй вариант:
1696 | ```python
1697 | myset1 = {1, 2, 3, 4, 5}
1698 | myset2 = {3, 4, 6, 7, 8}
1699 | myset3 = myset1 | myset2
1700 | print(myset3)
1701 | >>> {1, 2, 3, 4, 5, 6, 7, 8}
1702 | ```
1703 | Использование `update()`:
1704 | ```python
1705 | myset1 = {1, 2, 3, 4, 5}
1706 | myset2 = {3, 4, 6, 7, 8}
1707 | myset1.update(myset2) # изменяем множество myset1
1708 | print(myset1)
1709 | >>> {1, 2, 3, 4, 5, 6, 7, 8}
1710 | ```
1711 | Еще один способ:
1712 | ```python
1713 | myset1 = {1, 2, 3, 4, 5}
1714 | myset2 = {3, 4, 6, 7, 8}
1715 | myset1 |= myset2
1716 | print(myset1)
1717 | >>> {1, 2, 3, 4, 5, 6, 7, 8}
1718 |
1719 | ```
1720 | - Пересечение множеств: `intersection() `возвращает новое множество состоящее из элементов, принадлежащих одновременно каждому из пересекающихся множеств.
1721 | Для пересечения двух множеств можно также использовать оператор &.
1722 | Для изменения текущего множества используется метод `intersection_update()`.
1723 | Первый вариант:
1724 | ```python
1725 | myset1 = {1, 2, 3, 4, 5}
1726 | myset2 = {3, 4, 6, 7, 8}
1727 | myset3 = myset1.intersection(myset2)
1728 | print(myset3)
1729 | >>> {3, 4}
1730 | ```
1731 | Второй вариант:
1732 | ```python
1733 | myset1 = {1, 2, 3, 4, 5}
1734 | myset2 = {3, 4, 6, 7, 8}
1735 | myset3 = myset1 & myset2
1736 | print(myset3)
1737 | >>> {3, 4}
1738 | ```
1739 | Использование `intersection_update()`:
1740 | ```python
1741 | myset1 = {1, 2, 3, 4, 5}
1742 | myset2 = {3, 4, 6, 7, 8}
1743 | myset1.intersection_update(myset2) # изменяем множество myset1
1744 | print(myset1)
1745 | >>> {3, 4}
1746 | ```
1747 | Еще один способ:
1748 | ```python
1749 | myset1 = {1, 2, 3, 4, 5}
1750 | myset2 = {3, 4, 6, 7, 8}
1751 | myset1 &= myset2
1752 | print(myset1)
1753 | >>> {3, 4}
1754 | ```
1755 | - Разность множеств: `difference() `возвращает новое множество, в которое входят все элементы первого множества, не входящие во второе множество.
1756 | Для разности двух множеств можно также использовать оператор -.
1757 | Для изменения текущего множества используется метод `difference_update()`.
1758 | Первый вариант:
1759 | ```python
1760 | myset1 = {1, 2, 3, 4, 5}
1761 | myset2 = {3, 4, 6, 7, 8}
1762 | myset3 = myset1.difference(myset2)
1763 | print(myset3)
1764 | >>> {1, 2, 5}
1765 | ```
1766 | Второй вариант:
1767 | ```python
1768 | myset1 = {1, 2, 3, 4, 5}
1769 | myset2 = {3, 4, 6, 7, 8}
1770 | myset3 = myset1 - myset2
1771 | print(myset3)
1772 | >>> {1, 2, 5}
1773 | ```
1774 | Использование `difference_update()`:
1775 | ```python
1776 | myset1 = {1, 2, 3, 4, 5}
1777 | myset2 = {3, 4, 6, 7, 8}
1778 | myset1.difference_update(myset2) # изменяем множество myset1
1779 | print(myset1)
1780 | >>> {1, 2, 5}
1781 | ```
1782 | Еще один способ:
1783 | ```python
1784 | myset1 = {1, 2, 3, 4, 5}
1785 | myset2 = {3, 4, 6, 7, 8}
1786 | myset1 -= myset2
1787 | print(myset1)
1788 | >>> {1, 2, 5}
1789 | ```
1790 | - Симметричная разность множеств: `symmetric_difference() `возвращает новое множество, включающее все элементы исходных множеств, не принадлежащие одновременно обоим исходным множествам.
1791 | Для симметричной разности двух множеств можно также использовать оператор ^.
1792 | Для изменения текущего множества используется метод `symmetric_difference_update()`.
1793 | Первый вариант:
1794 | ```python
1795 | myset1 = {1, 2, 3, 4, 5}
1796 | myset2 = {3, 4, 6, 7, 8}
1797 | myset3 = myset1.symmetric_difference(myset2)
1798 | print(myset3)
1799 | >>> {1, 2, 5, 6, 7, 8}
1800 | ```
1801 | Второй вариант:
1802 | ```python
1803 | myset1 = {1, 2, 3, 4, 5}
1804 | myset2 = {3, 4, 6, 7, 8}
1805 | myset3 = myset1 ^ myset2
1806 | print(myset3)
1807 | >>> {1, 2, 5, 6, 7, 8}
1808 | ```
1809 | Использование `symmetric_difference_update()`:
1810 | ```python
1811 | myset1 = {1, 2, 3, 4, 5}
1812 | myset2 = {3, 4, 6, 7, 8}
1813 | myset1.symmetric_difference_update(myset2) # изменяем множество myset1
1814 | print(myset1)
1815 | >>> {1, 2, 5, 6, 7, 8}
1816 | ```
1817 | Еще один способ:
1818 | ```python
1819 | myset1 = {1, 2, 3, 4, 5}
1820 | myset2 = {3, 4, 6, 7, 8}
1821 | myset1 ^= myset2
1822 | print(myset1)
1823 | >>> {1, 2, 5, 6, 7, 8}
1824 |
1825 | ```
1826 | Подмножества и надмножества:
1827 | Любое множество – подмножество самого себя, про такое подмножество говорят "нестрогое подмножество".
1828 | Для определения, является ли одно из множеств подмножеством другого, используется метод `issubset(). `Данный метод возвращает значение `True`, если одно множество является подмножеством другого, и `False`, если не является
1829 | ```python
1830 | set1 = {2, 3}
1831 | set2 = {1, 2, 3, 4, 5, 6}
1832 | print(set1.issubset(set2))
1833 | >>> True
1834 |
1835 | ```
1836 | Для определения, является ли одно из множеств подмножеством другого, также применяются операторы <= (нестрогое подмножество) и < (строгое подмножество).
1837 | ```python
1838 | set1 = {2, 3}
1839 | set2 = {1, 2, 3, 4, 5, 6}
1840 | print(set1 <= set2)
1841 | >>> True
1842 |
1843 | ```
1844 | Для определения, является ли одно из множеств надмножеством другого, используется метод `issuperset()`. Данный метод возвращает значение `True`, если одно множество является надмножеством другого, в противном случае он возвращает `False`.
1845 | ```python
1846 | set1 = {'a', 'b', 'c', 'd', 'e'}
1847 | set2 = {'c', 'e'}
1848 | print(set1.issuperset(set2))
1849 | >>> True
1850 | ```
1851 | Для определения, является ли одно из множеств надмножеством другого, также применяются операторы >= (нестрогое надмножество) и > (строгое надмножество).
1852 | ```python
1853 | set1 = {'a', 'b', 'c', 'd', 'e'}
1854 | set2 = {'c', 'e'}
1855 | print(set1 >= set2)
1856 | >>> True
1857 | ```
1858 | Для определения отсутствия общих элементов в множествах используется метод `isdisjoint()`. Данный метод возвращает значение `True`, если множества не имеют общих элементов, и `False`, когда множества имеют общие элементы.
1859 | ```python
1860 | set1 = {1, 2, 3, 4, 5}
1861 | set2 = {5, 6, 7}
1862 | set3 = {7, 8, 9}
1863 | print(set1.isdisjoint(set2))
1864 | print(set1.isdisjoint(set3))
1865 | print(set2.isdisjoint(set3))
1866 | >>> False
1867 | >>> True
1868 | >>> False
1869 |
1870 | ```
1871 | ## Генераторы множеств
1872 | Чтобы заполнить множество всеми цифрами числа, можно использовать следующий код:
1873 | ```python
1874 | digits = {int(c) for c in input()}
1875 | ```
1876 | В генераторах можно использовать условия:
1877 | ```python
1878 | digits = {int(d) for d in 'abcd12ef78ghj90' if d.isdigit()}
1879 | ```
1880 | Данный код добавляет в `digits` только цифры.
1881 |
1882 | ## frozenset
1883 | frozenset – замороженный вариант множеств (set)
1884 | Синтаксис замороженных множеств полностью идентичен обычным.
1885 | Такие множества можно сравнивать с обычными.
1886 |
1887 | Зачем они нужны? Замороженные множества являются неизменяемыми, а значит могут быть элементами других множеств.
1888 |
1889 | # Словари
1890 | ## Введение
1891 | Словарь – изменяемый тип данных в Python. Левая часть – ключ, правая – значение.
1892 | Пример словаря:
1893 | ```python
1894 | languages = {'Python': 'Гвидо ван Россум',
1895 | 'C#': 'Андерс Хейлсберг',
1896 | 'Java': 'Джеймс Гослинг',
1897 | 'C++': 'Бьёрн Страуструп'}
1898 | ```
1899 | Код создает словарь, в котором ключом служит строка — название языка программирования, а значением — имя создателя языка. Важно! В рамках одного словаря каждый ключ уникален.
1900 |
1901 | Для извлечения элемента словаря используют ключ:
1902 | ```python
1903 | languages = {'Python': 'Гвидо ван Россум',
1904 | 'C#': 'Андерс Хейлсберг',
1905 | 'Java': 'Джеймс Гослинг',
1906 | 'C++': 'Бьёрн Страуструп'}
1907 |
1908 | print('Создателем языка C# является', languages['C#'])
1909 | >>> Создателем языка C# является Андерс Хейлсберг
1910 | ```
1911 | В отличие от списков, номеров позиций в словарях нет.
1912 |
1913 | Для вывода всего словаря можно использовать функцию `print()`:
1914 | ```python
1915 | info = {"name": "Nikita", "status": "Creator"}
1916 | print(info)
1917 | >>> {'name': 'Nikita', 'status': 'Creator'}
1918 | ```
1919 | Начиная с версии Python 3.6, словари являются упорядоченными, то есть сохраняют порядок следования ключей в порядке их внесения в словарь.
1920 |
1921 | ## Создание словаря
1922 | Если ключи словаря — строки без каких-либо специальных символов, то для создания словаря можно использовать функцию `dict(). `Пример:
1923 | ```python
1924 | info = dict(name='Timur', age=28, job='Teacher')
1925 |
1926 | ```
1927 | Создание на основе списка кортежей:
1928 | ```python
1929 | info_list = [('name', 'Timur'), ('age', 28), ('job', 'Teacher')] # список кортежей
1930 | info_dict = dict(info_list) # создаем словарь на основе списка кортежей
1931 |
1932 | ```
1933 | Создание на основе кортежа списков:
1934 | ```python
1935 | info_tuple = (['name', 'Timur'], ['age', 28], ['job', 'Teacher']) # кортеж списков
1936 | info_dict = dict(info_tuple) # создаем словарь на основе кортежа списков
1937 |
1938 | ```
1939 | Если необходимо создать словарь, каждому ключу которого соответствует одно и то же значение, можно воспользоваться методом `fromkeys()`.
1940 | ```python
1941 | dict1 = dict.fromkeys(['name', 'age', 'job'], 'Missed information')
1942 | ```
1943 | Если методу `fromkeys()` не передать второй параметр, то по умолчанию присваивается значение `None`.
1944 |
1945 | Создать словарь на основании двух списков (кортежей) можно с помощью встроенной функции-упаковщика `zip().`
1946 | ```python
1947 | keys = ['name', 'age', 'job']
1948 | values = ['Timur', 28, 'Teacher']
1949 | info = dict(zip(keys, values))
1950 | print(info)
1951 | >>> {'name': 'Timur', 'age': 28, 'job': 'Teacher'}
1952 | ```
1953 | В случае несовпадения длины списков функция самостоятельно отсечет лишние элементы.
1954 |
1955 | ## Создание пустого словаря
1956 | Создать пустой словарь можно двумя способами:
1957 | - с помощью пустых фигурных скобок
1958 | - с помощью функции `dict()`
1959 |
1960 | ## Важные детали
1961 | - Ключи должны быть уникальными
1962 | - Ключи должны быть неизменяемым типом данных
1963 | - Значения могут относиться к любому типу данных, их тип данных произволен
1964 | - Обращение по индексу и срезы недоступны для словарей
1965 | - Операция конкатенации + и умножения на число * недоступны для словарей
1966 |
1967 |
1968 | ## Основы (len, sum, min, max, in)
1969 | - Длиной словаря называется количество его элементов. Для определения длины словаря используют встроенную функцию `len()`.
1970 | ```python
1971 | fruits = {'Apple': 70, 'Grape': 100, 'Banana': 80}
1972 | print(len(fruits))
1973 | >>> 3
1974 | ```
1975 | - Встроенная функция `sum() `принимает в качестве аргумента словарь с числовыми ключами и вычисляет сумму его ключей.
1976 | ```python
1977 | my_dict = {10: 'Россия', 20: 'США', 30: 'Франция'}
1978 | print('Сумма всех ключей словаря =', sum(my_dict))
1979 | >>> Сумма всех ключей словаря = 60
1980 | ```
1981 | - Встроенные функции `min() `и `max() `принимают в качестве аргумента словарь и находят минимальный и максимальный ключ соответственно, при этом ключ может принадлежать к любому типу данных, для которого возможны операции порядка <, <=, >, >= (числа, строки, и т.д.).
1982 | ```python
1983 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'}
1984 | months = {1: 'Январь', 2: 'Февраль', 3: 'Март'}
1985 | print('Минимальный ключ =', min(capitals))
1986 | print('Максимальный ключ =', max(months))
1987 | >>> Минимальный ключ = Россия
1988 | >>> Максимальный ключ = 3
1989 | ```
1990 | - Оператор `in` позволяет проверить, содержит ли словарь заданный ключ.
1991 | ```python
1992 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'}
1993 | if 'Франция' in capitals:
1994 | print('Столица Франции - это', capitals['Франция'])
1995 | >>> Столица Франции - это Париж
1996 |
1997 | ```
1998 | ## Сравнение словарей
1999 | Словари можно сравнивать между собой. Равные словари имеют одинаковое количество элементов и содержат равные элементы (ключ: значение). Для сравнения словарей используются операторы == и !=.
2000 |
2001 | ## Перебор элементов словаря
2002 | Вывод ключей словаря:
2003 | ```python
2004 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'}
2005 | for key in capitals:
2006 | print(key)
2007 | >>> Россия
2008 | >>> Франция
2009 | >>> Чехия
2010 | ```
2011 | Вывод значений словаря:
2012 | ```python
2013 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'}
2014 | for key in capitals:
2015 | print(capitals[key])
2016 | >>> Москва
2017 | >>> Париж
2018 | >>> Прага
2019 |
2020 | ```
2021 | ## Распаковка словарей
2022 | При распаковке словарей возвращаются только ключи:
2023 | ```python
2024 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'}
2025 | print(*capitals, sep='\n')
2026 | >>> Россия
2027 | >>> Франция
2028 | >>> Чехия
2029 |
2030 | ```
2031 | ## Методы keys(), values(), items()
2032 | Словарный метод `keys()` возвращает список ключей всех элементов словаря.
2033 | ```python
2034 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'}
2035 | for key in capitals.keys(): # итерируем по списку ['Россия', 'Франция', 'Чехия']
2036 | print(key)
2037 | >>> Россия
2038 | >>> Франция
2039 | >>> Чехия
2040 |
2041 | ```
2042 | Словарный метод `values() `возвращает список значений всех элементов словаря.
2043 | ```python
2044 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'}
2045 | for value in capitals.values(): # итерируем по списку ['Москва', 'Париж', 'Прага']
2046 | print(value)
2047 | >>> Москва
2048 | >>> Париж
2049 | >>> Прага
2050 |
2051 | ```
2052 | Словарный метод `items() `возвращает список всех элементов словаря, состоящий из кортежей пар (ключ, значение).
2053 | ```python
2054 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'}
2055 | for item in capitals.items():
2056 | print(item)
2057 | >>> ('Россия', 'Москва')
2058 | >>> ('Франция', 'Париж')
2059 | >>> ('Чехия', 'Прага')
2060 | ```
2061 | Можно писать такой код:
2062 | ```python
2063 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'}
2064 | for key, value in capitals.items():
2065 | print(key, '-', value)
2066 | >>> Россия - Москва
2067 | >>> Франция - Париж
2068 | >>> Чехия – Прага
2069 |
2070 | ```
2071 | ## Сортировка словарей
2072 | Сортировка по ключам выполняется с использованием функции `sorted()`.
2073 | Важно: словари не содержат метода `sort()`.
2074 | ```python
2075 | capitals = {'Россия': 'Москва', 'Англия': 'Лондон', 'Чехия': 'Прага', 'Бразилия': 'Бразилиа'}
2076 | for key in sorted(capitals):
2077 | print(key)
2078 | >>> Англия
2079 | >>> Бразилия
2080 | >>> Россия
2081 | >>> Чехия
2082 |
2083 | ```
2084 | ## Методы словарей
2085 | - Добавление и изменение элементов в словаре
2086 | Чтобы изменить значение по определенному ключу в словаре, достаточно использовать индексацию вместе с оператором присваивания. При этом если ключ уже присутствует в словаре, его значение заменяется новым, если же ключ отсутствует – то в словарь будет добавлен новый элемент.
2087 | ```python
2088 | info = {"name": "Sam", "age": 28, "job": "Teacher"}
2089 | info["name"] = "Timur" # изменяем значение по ключу name
2090 | info["email"] = "timyr-guev@yandex.ru" # добавляем в словарь элемент с ключом email
2091 | print(info)
2092 | >>> {'name': 'Timur', 'age': 28, 'job': 'Teacher', 'email': 'timyr-guev@yandex.ru'}
2093 | ```
2094 | - Метод `get()`
2095 | Для того чтобы избежать возникновения ошибки в случае отсутствия ключа в словаре, можно использовать метод `get(),` способный кроме ключа принимать и второй аргумент — значение, которое вернется, если заданного ключа нет. Когда второй аргумент не указан, то метод в случае отсутствия ключа возвращает `None.`
2096 | ```python
2097 | info = {"name": "Bob", "age": 25, "job": "Dev"}
2098 | item1 = info.get("salary")
2099 | item2 = info.get("salary", "Информации о зарплате нет")
2100 | print(item1)
2101 | print(item2)
2102 | >>> None
2103 | >>> Информации о зарплате нет
2104 | ```
2105 | - Метод `update()`
2106 | Метод `update()` реализует своеобразную операцию конкатенации для словарей. Он объединяет ключи и значения одного словаря с ключами и значениями другого. При совпадении ключей в итоге сохранится значение словаря, указанного в качестве аргумента метода `update()`.
2107 | ```python
2108 | info1 = {"name": "Bob", "age": 25, "job": "Dev"}
2109 | info2 = {"age": 30, "city": "New York", "email": "bob@web.com"}
2110 | info1.update(info2)
2111 | print(info1)
2112 | >>> {'name': 'Bob', 'age': 30, 'job': 'Dev', 'city': 'New York', 'email': 'bob@web.com'}
2113 | ```
2114 | В Python 3.9 появились операторы | и |=, которые реализуют операцию конкатенации словарей.
2115 | ```python
2116 | info1 = {"name": "Bob", "age": 25, "job": "Dev"}
2117 | info2 = {"age": 30, "city": "New York", "email": "bob@web.com"}
2118 | info1 |= info2
2119 | print(info1)
2120 | >>> {'name': 'Bob', 'age': 30, 'job': 'Dev', 'city': 'New York', 'email': 'bob@web.com'}
2121 | ```
2122 | - Метод `setdefault()`
2123 | Метод `setdefault()` позволяет получить значение из словаря по заданному ключу, автоматически добавляя элемент словаря, если он отсутствует.
2124 | ```python
2125 | info = {"name": "Bob", "age": 25, "job": "Dev"}
2126 | print(info.setdefault("name", "Tim"))
2127 | >>> Bob
2128 |
2129 | info = {"age": 25, "job": "Dev"}
2130 | print(info.setdefault("name", "Tim"))
2131 | >>> Tim
2132 | ```
2133 | - Оператор `del`
2134 | ```python
2135 | info = {"name": "Sam", "age": 28, "job": "Teacher", "email": "timyr-guev@yandex.ru"}
2136 | del info["email"] # удаляем элемент имеющий ключ email
2137 | del info["job"] # удаляем элемент имеющий ключ job
2138 | print(info)
2139 | >>> {'name': 'Sam', 'age': 28}
2140 | ```
2141 | - Метод `pop()`
2142 | ```python
2143 | info = {"name": "Sam", "age": 28, "job": "Teacher", "email": "timyr-guev@yandex.ru"}
2144 | email = info.pop('email') # удаляем элемент по ключу email, возвращая его значение
2145 | job = info.pop('job') # удаляем элемент по ключу job, возвращая его значение
2146 | print(email)
2147 | print(job)
2148 | print(info)
2149 | >>> timyr-guev@yandex.ru
2150 | >>> Teacher
2151 | >>> {'name': 'Sam', 'age': 28}
2152 | ```
2153 | Также можно указать второй аргумент, он будет возвращен, если указанного ключа в словаре нет. Это позволяет реализовать безопасное удаление элемента из словаря:
2154 | ```python
2155 | surname = info.pop('surname', None)
2156 | ```
2157 | - Метод `popitem() `удаляет из словаря последний добавленный элемент и возвращает удаляемый элемент в виде кортежа (ключ, значение).
2158 | ```python
2159 | info = {"name": "Bob", "age": 25, "job": "Dev"}
2160 | info["surname"] = "Sinclar"
2161 | item = info.popitem()
2162 | print(item)
2163 | print(info)
2164 | >>> ('surname', 'Sinclar')
2165 | >>> {'name': 'Bob', 'age': 25, 'job': 'Dev'}
2166 | ```
2167 | - Метод `clear()` удаляет все элементы из словаря.
2168 | - Метод `copy() `создает поверхностную копию словаря.
2169 |
2170 | ## Генераторы словарей
2171 | Генераторы словарей имеют такой же синтаксис как и в генераторах списков.
2172 | ```python
2173 | squares = {i: i**2 for i in range(6)} # квадраты чисел от 0 до 5
2174 | print(squares)
2175 | >>> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
2176 | ```
2177 | В генераторах словарей можно использовать условия:
2178 | ```python
2179 | squares = {i: i**2 for i in range(10) if i % 2 == 0}
2180 | print(squares)
2181 | >>> {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
2182 |
2183 | ```
2184 | ## Вложенные словари
2185 | Вложенный словарь создается как обычный, только каждое значение в нем – другой словарь.
2186 | Пример:
2187 | ```python
2188 | info = {'emp1': {'name': 'Timur', 'job': 'Teacher'},
2189 | 'emp2': {'name': 'Ruslan', 'job': 'Developer'},
2190 | 'emp3': {'name': 'Rustam', 'job': 'Tester'}}
2191 | ```
2192 | Или так:
2193 | ```python
2194 | info = dict(emp1 = {'name': 'Timur', 'job': 'Teacher'},
2195 | emp2 = {'name': 'Ruslan', 'job': 'Developer'},
2196 | emp3 = {'name': 'Rustam', 'job': 'Tester'})
2197 |
2198 | ```
2199 | Для обращения по индексу используют такой код:
2200 | ```python
2201 | info = {'emp1': {'name': 'Timur', 'job': 'Teacher'},
2202 | 'emp2': {'name': 'Ruslan', 'job': 'Developer'},
2203 | 'emp3': {'name': 'Rustam', 'job': 'Tester'}}
2204 |
2205 | print(info['emp1']['name'])
2206 | print(info['emp2']['job'])
2207 | >>> Timur
2208 | >>> Developer
2209 |
2210 | ```
2211 | Изменение вложенных словарей:
2212 | ```python
2213 | info = {'emp1': {'name': 'Timur', 'job': 'Teacher'},
2214 | 'emp2': {'name': 'Ruslan', 'job': 'Developer'},
2215 | 'emp3': {'name': 'Rustam', 'job': 'Tester'}}
2216 |
2217 | info['emp1']['job'] = 'Manager'
2218 | print(info['emp1'])
2219 | >>> {'name': 'Timur', 'job': 'Manager'}
2220 |
2221 | ```
2222 | Итерация по вложенным словарям:
2223 | ```python
2224 | info = {'emp1': {'name': 'Timur', 'job': 'Teacher'},
2225 | 'emp2': {'name': 'Ruslan', 'job': 'Developer'},
2226 | 'emp3': {'name': 'Rustam', 'job': 'Tester'}}
2227 |
2228 | for emp in info:
2229 | print('Employee ID:', emp)
2230 | for key in info[emp]:
2231 | print(key + ':', info[emp][key])
2232 | print()
2233 | >>> Employee ID: emp1
2234 | >>> name: Timur
2235 | >>> job: Teacher
2236 |
2237 | >>> Employee ID: emp2
2238 | >>> name: Ruslan
2239 | >>> job: Developer
2240 |
2241 | >>> Employee ID: emp3
2242 | >>> name: Rustam
2243 | >>> job: Tester
2244 |
2245 | ```
2246 | # Модули random, string, Метод Монте-Карло, Bogosort
2247 | ## Модуль random
2248 | ```python
2249 | import random
2250 |
2251 | num = random.randint(0, 17) # случайное целое число от 0 до 17 (включительно)
2252 | print(num)
2253 | >>> 14
2254 |
2255 | num1 = random.randrange(0, 100, 10) # возвращает случайное число от m до n с шагом k. синтаксис идентичен range() (не включительно)
2256 | num2 = random.randrange(0, 100, 10) # возвращает случайное число от m до n с шагом k. синтаксис идентичен range() (не включительно)
2257 | num3 = random.randrange(0, 100, 10) # возвращает случайное число от m до n с шагом k. синтаксис идентичен range() (не включительно)
2258 | print(num1, num2, num3)
2259 | >>> 80 30 50
2260 |
2261 | num = random.random() # случайное число с плавающей точкой от 0.0 до 1.0, аргументы не указываются (не включительно)
2262 | print(num)
2263 | >>> 0.34980886772220243
2264 |
2265 | num = random.uniform(3.6, 9.2) # случайное число с плавающей точкой от 3.6 до 9.2, аргументы обязательны (включительно)
2266 | print(num)
2267 | >>> 6.574427819432531
2268 | ```
2269 | Методы строк и списков:
2270 | ```python
2271 | import random
2272 |
2273 | numbers = [1, 2, 3, 4, 5, 6, 7, 8]
2274 | random.shuffle(numbers) # перемешивает список
2275 | print(numbers)
2276 | >>> [3, 6, 7, 1, 5, 8, 2, 4]
2277 |
2278 | print(random.choice('Ваня, привет')) # случайный символ из строки или случайный элемент из списка
2279 | >>> я
2280 |
2281 | numbers = [12, 89, 27, 46]
2282 | print(random.sample(numbers, 3)) # выводит 3 случайных элемента из списка numbers
2283 | >>> [46, 89, 27]
2284 |
2285 | ```
2286 | В модуле random можно задать сид (англ. seed - семя). При одинаковых сидах одинаковый код рандома выдаст одинаковых результат. По умолчанию, начальным значением генератора является системное время (текущая дата и время). Пример:
2287 | ```python
2288 | import random
2289 | random.seed(17) # явно устанавливаем начальное значение для генератора случайных чисел
2290 | for _ in range(10):
2291 | print(random.randint(1, 100))
2292 | >>> 67
2293 | >>> 54
2294 | >>> 39
2295 | >>> 47
2296 | >>> 38
2297 | >>> 23
2298 | >>> 99
2299 | >>> 91
2300 | >>> 91
2301 | >>> 70
2302 | ```
2303 | Попробуйте этот код, он выведет тоже самое что и в примере.
2304 |
2305 | ## Модуль string
2306 | В модуле string есть удобные константы:
2307 | ```python
2308 | import string
2309 |
2310 | print(string.ascii_letters)
2311 | print(string.ascii_uppercase)
2312 | print(string.ascii_lowercase)
2313 | print(string.digits)
2314 | print(string.hexdigits)
2315 | print(string.octdigits)
2316 | print(string.punctuation)
2317 | print(string.printable)
2318 | >>> abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
2319 | >>> ABCDEFGHIJKLMNOPQRSTUVWXYZ
2320 | >>> abcdefghijklmnopqrstuvwxyz
2321 | >>> 0123456789
2322 | >>> 0123456789abcdefABCDEF
2323 | >>> 01234567
2324 | >>> !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
2325 | >>> 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ \t\n\r\x0b\x0c
2326 |
2327 | ```
2328 | ## Метод Монте-Карло
2329 | При помощи метода Монте-Карло можно вычислить примерную площадь фигуры.
2330 | Фигура:
2331 | 
2332 | Формула:
2333 | −2 ≤ x ≤ 2
2334 | −2 ≤ y ≤ 2
2335 | x^3 + y^4 + 2 ≥ 0
2336 | 3x + y^2 ≤ 2
2337 |
2338 | Задача вычислить примерную площадь фигуры.
2339 | Решение:
2340 | ```python
2341 | from random import uniform
2342 |
2343 | n = 10**6 # количество испытаний
2344 | k = 0 # количество попавших точек
2345 | S = 16 # площадь квадрата, в который вписана фигура
2346 |
2347 | for _ in range(n):
2348 | x = uniform(-2, 2) # рандомное число от минимальной до максимальной возможной координаты
2349 | y = uniform(-2, 2) # рандомное число от минимальной до максимальной возможной координаты
2350 | if (x**3 + y**4 + 2 >= 0) and (3*x + y**2 <= 2): # если точка внутри фигуры
2351 | k += 1 # увеличиваем количество попавших точек
2352 |
2353 | print((k/n) * S) # (точек / метр) * площадь квадрата
2354 |
2355 | ```
2356 | ## Bogosort
2357 | Болотная сортировка (Bogosort) — неэффективный алгоритм сортировки, используемый только в образовательных целях и противопоставляемый другим, более реалистичным алгоритмам.
2358 | Принцип работы алгоритма прост, как плесень. Перетряхиваем список случайным образом до тех пор пока он внезапно не отсортируется. Процесс может счастливо завершиться сразу, а может длиться до тепловой смерти Вселенной. Это уж как повезёт.
2359 | Реализация алгоритма:
2360 |
2361 | ```python
2362 | import random
2363 |
2364 | def is_sorted(nums): # отсортирован ли список?
2365 | for i in range(len(nums) - 1):
2366 | if nums[i] > nums[i + 1]:
2367 | return False
2368 | return True
2369 |
2370 | def bogosort(nums): # реализация алгоритма болотной сортировки
2371 | while not is_sorted(nums):
2372 | random.shuffle(nums)
2373 | return nums
2374 |
2375 | numbers = list(range(10))
2376 | random.shuffle(numbers) # перемешиваем начальный список
2377 | print(numbers) # выводим начальный список
2378 |
2379 | sorted_numbers = bogosort(numbers)
2380 |
2381 | print(sorted_numbers)
2382 |
2383 | ```
2384 | # Модули decimal, fractions и complex
2385 | ## Модуль decimal: введение
2386 | Тип данных float не стоит использовать в случаях, когда важна точность:
2387 | ```python
2388 | num = 0.1 + 0.1 + 0.1
2389 |
2390 | if num == 0.3:
2391 | print('YES')
2392 | else:
2393 | print('NO')
2394 | print(num)
2395 | >>> NO
2396 | >>> 0.30000000000000004
2397 | ```
2398 | Для точных расчетов рекомендуется использовать модуль decimal и тип данных Decimal.
2399 | Тип данных Decimal неизменяемый, также он в разы медленнее float.
2400 |
2401 | ## Создание Decimal чисел
2402 | Создать Decimal число можно из строки (str) или из числа с плавающей точкой (float):
2403 | ```python
2404 | from decimal import *
2405 |
2406 | d1 = Decimal(1)
2407 | d2 = Decimal(567)
2408 | d3 = Decimal(-93)
2409 | d4 = Decimal('12345')
2410 | d5 = Decimal('52.198')
2411 |
2412 | print(d1, d2, d3, d4, d5, sep='\n')
2413 | >>> 1
2414 | >>> 567
2415 | >>> -93
2416 | >>> 12345
2417 | >>> 52.198
2418 | ```
2419 | Не стоит создавать Decimal из float, в Decimal попадает уже “неправильное” число
2420 | ```python
2421 | from decimal import *
2422 |
2423 | num = Decimal(0.1)
2424 | print(num)
2425 | >>> 0.1000000000000000055511151231257827021181583404541015625
2426 |
2427 | ```
2428 | ## Арифметические операции над Decimal числами
2429 | Тип данных Decimal отлично интегрирован в язык Python. С Decimal числами работают все привычные операции: сложение, вычитание, умножение, деление, возведение в степень.
2430 | ```python
2431 | from decimal import *
2432 |
2433 | num1 = Decimal('5.8')
2434 | num2 = Decimal('2.5')
2435 |
2436 | print(num1 + num2)
2437 | print(num1 - num2)
2438 | print(num1 * num2)
2439 | print(num1 / num2)
2440 | print(num1 // num2)
2441 | print(num1 ** num2)
2442 | >>> 8.3
2443 | >>> 3.3
2444 | >>> 14.50
2445 | >>> 2.32
2446 | >>> 2
2447 | >>> 81.01584832611456399030280565
2448 |
2449 | ```
2450 | Можно совершать арифметические операции над Decimal и целыми числами (миксовать Decimal и int), но не рекомендуется смешивать их с float.
2451 |
2452 | ## Математические функции Decimal чисел
2453 | Decimal числа можно передавать как аргументы функциям, ожидающим float. Они будут преобразованы во float. К примеру, модуль math, оперирующий float числами, может работать и с Decimal числами.
2454 | ```python
2455 | from decimal import *
2456 | from math import *
2457 |
2458 | num1 = Decimal('1.44')
2459 | num2 = Decimal('0.523')
2460 |
2461 | print(sqrt(num1))
2462 | print(sin(num2))
2463 | print(log(num1 + num2))
2464 | >>> 1.2
2465 | >>> 0.4994813555186418
2466 | >>> 0.6744739152943241
2467 | ```
2468 | Важно понимать, что результатом работы функции модуля math являются float числа, а не Decimal.
2469 | У модуля decimal есть встроенные математические методы, которые возвращают число с типом данных Decimal:
2470 | | Функция | Описание |
2471 | |---|---|
2472 | | sqrt() | вычисляет квадратный корень из Decimal числа |
2473 | | exp() | возвращает e^x для Decimal числа |
2474 | | ln() | вычисляет натуральный логарифм (по основанию e) Decimal числа |
2475 | | log10() | вычисляет десятичный логарифм (по основанию 10) Decimal числа |
2476 |
2477 | ```python
2478 | from decimal import *
2479 |
2480 | num = Decimal('10.0')
2481 |
2482 | print(num.sqrt())
2483 | print(num.exp())
2484 | print(num.ln())
2485 | print(num.log10())
2486 | >>> 3.162277660168379331998893544
2487 | >>> 22026.46579480671651695790065
2488 | >>> 2.302585092994045684017991455
2489 | >>> 1
2490 |
2491 | ```
2492 | Тип данных Decimal также содержит полезный метод `as_tuple()` который возвращает кортеж из 3 элементов:
2493 | - sign – знак числа (0 для положительного числа и 1 для отрицательного числа)
2494 | - digits – цифры числа
2495 | - exponent – значение экспоненты (количество цифр после точки, умноженное на -1)
2496 |
2497 | ```python
2498 | from decimal import *
2499 |
2500 | num1 = Decimal('-1.4568769017')
2501 | num2 = Decimal('0.523')
2502 |
2503 | print(num1.as_tuple())
2504 | print(num2.as_tuple())
2505 | >>> DecimalTuple(sign=1, digits=(1, 4, 5, 6, 8, 7, 6, 9, 0, 1, 7), exponent=-10)
2506 | >>> DecimalTuple(sign=0, digits=(5, 2, 3), exponent=-3)
2507 |
2508 | ```
2509 | Удобно использовать следующий код:
2510 | ```python
2511 | from decimal import *
2512 |
2513 | num = Decimal('-1.4568769017')
2514 | num_tuple = num.as_tuple()
2515 |
2516 | print(num_tuple.sign)
2517 | print(num_tuple.digits)
2518 | print(num_tuple.exponent)
2519 | >>> 1
2520 | >>> (1, 4, 5, 6, 8, 7, 6, 9, 0, 1, 7)
2521 | >>> -10
2522 |
2523 | ```
2524 | ## Работа с контекстом Decimal чисел
2525 | Базовые параметры Decimal можно посмотреть в его контексте, выполнив функцию `getcontext():`
2526 | ```python
2527 | from decimal import *
2528 | print(getcontext())
2529 | >>> Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0,
2530 | flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
2531 | ```
2532 | Мы видим здесь, что точность 28 знаков, округление к ближайшему четному, пределы по экспоненте ± 999999, capitals – это про заглавную Е при печати, включенные ловушки – неправильная операция, деление на ноль, переполнение.
2533 |
2534 | ## Точность Decimal чисел
2535 | Контекстом в Decimal можно управлять, устанавливая свои значения. Например, чтобы управлять точностью Decimal, необходимо изменить параметр контекста prec (от англ. precision – точность).
2536 | ```python
2537 | from decimal import *
2538 |
2539 | getcontext().prec = 3 # устанавливаем точность в 3 знака
2540 | num = Decimal('3.1415')
2541 |
2542 | print(num)
2543 | print(num * 1)
2544 | print(num * 2)
2545 | print(num / 2)
2546 | >>> 3.1415
2547 | >>> 3.14
2548 | >>> 6.28
2549 | >>> 1.57
2550 | ```
2551 | Обратите внимание на то, что точность вступает в силу только во время арифметических операций, а не при создании самих чисел.
2552 |
2553 | ## Округление Decimal чисел
2554 | Округляют числа Decimal с помощью метода `quantize()`. Этот метод в качестве первого аргумента принимает объект Decimal, указывающий на формат округления.
2555 | ```python
2556 | from decimal import *
2557 |
2558 | getcontext().prec = 4 # устанавливаем точность числа
2559 | num = Decimal('3.1415926535')
2560 |
2561 | print(num.quantize(Decimal('1.000'))) # округление до 3 цифр в дробной части
2562 | print(num.quantize(Decimal('1.00'))) # округление до 2 цифр в дробной части
2563 | print(num.quantize(Decimal('1.0'))) # округление до 1 цифр в дробной части
2564 | >>> 3.142
2565 | >>> 3.14
2566 | >>> 3.1
2567 |
2568 | ```
2569 | Если точность округления установлена в 2, а формат округления `Decimal('1.00')`, то возникнет ошибка:
2570 | ```python
2571 | from decimal import *
2572 |
2573 | getcontext().prec = 2 # устанавливаем точность округления
2574 | num = Decimal('3.1415926535')
2575 |
2576 | print(num.quantize(Decimal('1.00'))) # округление до 2 цифр в дробной части
2577 | >>> decimal.InvalidOperation: []
2578 |
2579 | ```
2580 | Помимо первого параметра, метод `quantize()` принимает в качестве второго параметра стратегию округления:
2581 | - ROUND_CEILING – округление в направлении бесконечности (Infinity)
2582 | - ROUND_FLOOR – округляет в направлении минус бесконечности (- Infinity)
2583 | - ROUND_DOWN – округление в направлении нуля
2584 | - ROUND_HALF_EVEN – округление до ближайшего четного числа, число 6.5 округлится не до 7, а до 6
2585 | - ROUND_HALF_DOWN – округление до ближайшего нуля
2586 | - ROUND_UP – округление от нуля
2587 | - ROUND_05UP – округление от нуля (если последняя цифра после округления до нуля была бы 00 или 55, в противном случае – к нулю).
2588 |
2589 | ```python
2590 | from decimal import *
2591 |
2592 | num = Decimal('3.456')
2593 |
2594 | print(num.quantize(Decimal('1.00'), ROUND_CEILING))
2595 | print(num.quantize(Decimal('1.00'), ROUND_FLOOR))
2596 | >>> 3.46
2597 | >>> 3.45
2598 |
2599 | ```
2600 | ## Сравнение float и Decimal чисел
2601 | | Характеристика / тип | float | Decimal |
2602 | |---|---|---|
2603 | | Реализация | аппаратная | программная |
2604 | | Размер | 64 бит | не ограничен |
2605 | | Основание экспоненты | 2 | 10 |
2606 | | Скорость | + | - |
2607 | | Настраиваемость | - | + |
2608 | | Для финансов и бизнеса | - | + |
2609 | | Для симуляций, визуализаций и игр | + | - |
2610 | | Для высокоточных вычислений | - | + |
2611 |
2612 | ## Важные примечания для decimal
2613 | - Decimal числа можно сравнивать между собой, как обычные числа, причем в отличие от float чисел допускается и точное равенство.
2614 | ```python
2615 | from decimal import *
2616 |
2617 | num = Decimal("0.1")
2618 | if num * 3 == Decimal("0.3"):
2619 | print("YES")
2620 | else:
2621 | print("NO")
2622 | >>> YES
2623 |
2624 | ```
2625 | - Можно сортировать списки с Decimal числами и искать минимум и максимум среди них.
2626 | ```python
2627 | from decimal import *
2628 |
2629 | s = '1.34 3.45 1.00 0.03 9.25'
2630 |
2631 | numbers = [Decimal(i) for i in s.split()]
2632 |
2633 | maximum = max(numbers)
2634 | minimum = min(numbers)
2635 |
2636 | numbers.sort()
2637 |
2638 | print(maximum)
2639 | print(minimum)
2640 | print(numbers)
2641 | >>> 9.25
2642 | >>> 0.03
2643 | >>> [Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('3.45'), Decimal('9.25')]
2644 |
2645 | ```
2646 | - Чтобы не писать каждый раз название типа, можно использовать приведенный ниже код:
2647 | ```python
2648 | from decimal import Decimal as D
2649 |
2650 | num1 = D("1.5") + D("3.2")
2651 | num2 = D("1.4") * D("2.5")
2652 |
2653 | print(num1)
2654 | print(num2)
2655 | >>> 4.7
2656 | >>> 3.50
2657 | ```
2658 | ## Модуль fractions: введение
2659 | Рациональное число – это число, которое можно представить в виде дроби m/n, где m, n соответственно, числитель и знаменатель, которые имеют целочисленное значение, при этом знаменатель не равен нулю.
2660 | Например, в дроби 5/6 числитель m=5, а знаменатель n=6.
2661 | Знаменатель дроби показывает количество равных частей, а числитель дроби показывает, сколько из них взято.
2662 | 
2663 |
2664 | ## Тип данных Fraction
2665 | Для работы с рациональными числами в Python используется тип данных Fraction. Тип данных Fraction как и Decimal реализован программно, поэтому он в разы медленнее встроенных числовых типов данных int и float. Тип данных Fraction неизменяемый. Операции над данными этого типа приводят к созданию новых объектов, при этом старые не меняются.
2666 | Чтобы использовать возможности типа данных Fraction, нужно предварительно подключить модуль fractions:
2667 | ```python
2668 | from fractions import Fraction
2669 |
2670 | ```
2671 | ## Создание Fraction чисел
2672 | Создать Fraction число можно несколькими способами:
2673 | - из целых чисел, передав значения числителя и знаменателя дроби
2674 | - из строки на основании десятичного представления
2675 | - из строки на основании обыкновенной дроби
2676 | - из числа с плавающей точкой (не рекомендуется)
2677 |
2678 | ```python
2679 | from fractions import Fraction
2680 |
2681 | num1 = Fraction(7, 32) # 7 - числитель, 32 - знаменатель
2682 | num2 = Fraction('0.67')
2683 | num3 = Fraction('1/45')
2684 |
2685 | print(num1, num2, num3, sep='\n')
2686 | >>> 7/32
2687 | >>> 67/100
2688 | >>> 1/45
2689 |
2690 | ```
2691 | Не стоит создавать Fraction из float:
2692 | ```python
2693 | from fractions import Fraction
2694 |
2695 | num = Fraction(0.34)
2696 |
2697 | print(num) # Вместо 17/50 код выведет:
2698 | >>> 6124895493223875/18014398509481984
2699 |
2700 | ```
2701 | ## Основы типа данных Fraction
2702 | Обратите внимание на то, что при создании рационального числа Fraction, автоматически происходит сокращение числителя и знаменателя дроби:
2703 | ```python
2704 | from fractions import Fraction
2705 |
2706 | num = Fraction(4, 8)
2707 |
2708 | print(num)
2709 | >>> 1/2
2710 |
2711 | ```
2712 | Вывод дробей, являющихся целыми числами:
2713 | ```python
2714 | from fractions import Fraction
2715 |
2716 | num = Fraction(5, 1)
2717 |
2718 | print(num)
2719 | >>> 5
2720 |
2721 | ```
2722 | Для того чтобы каждый раз не писать название типа, можно использовать следующий код:
2723 | ```python
2724 | from fractions import Fraction as F
2725 |
2726 | num1 = F('1/5') + F('3/2')
2727 | num2 = F('1/4') * F('2/5')
2728 |
2729 | print(num1)
2730 | print(num2)
2731 |
2732 | ```
2733 | ## Сравнение Fraction чисел
2734 | Fraction числа можно сравнивать между собой точно так же, как и любые другие числа. Доступны 6 основных операторов сравнения:
2735 | ```
2736 | - >: больше
2737 | - <: меньше
2738 | - >=: больше либо равно
2739 | - <=: меньше либо равно
2740 | - ==: в точности равно
2741 | - !=: не равно
2742 | ```
2743 | Обратите внимание на то, что мы можем сравнивать Fraction числа и целые числа (числа с плавающей точкой) без явного приведения типов.
2744 |
2745 | ## Арифметические операции над Fraction числами
2746 | Тип данных Fraction отлично интегрирован в язык Python. С Fraction числами работают все привычные операции: сложение, вычитание, умножение, деление, возведение в степень.
2747 | Мы также можем совершать арифметические операции над Fraction и целыми числами (миксовать Fraction и int), но не рекомендуется смешивать их с float.
2748 | Обратите внимание на то, что операция возведения в степень (**) для Fraction чисел может возвращать вещественный результат:
2749 | ```python
2750 | from fractions import Fraction
2751 |
2752 | num1 = Fraction('3/8')
2753 | num2 = Fraction('1/2')
2754 |
2755 | print(num1 ** num2)
2756 | >>> 0.6123724356957945
2757 |
2758 | ```
2759 | ## Математические функции
2760 | Fraction числа можно передавать как аргументы функций, ожидающих float. Тогда они будут преобразованы во float. К примеру, модуль math, оперирующий float числами, может работать и с Fraction числами.
2761 | ```python
2762 | from fractions import Fraction
2763 | from math import *
2764 |
2765 | num1 = Fraction('1.44')
2766 | num2 = Fraction('0.523')
2767 |
2768 | print(sqrt(num1))
2769 | print(sin(num2))
2770 | print(log(num1 + num2))
2771 | >>> 1.2
2772 | >>> 0.4994813555186418
2773 | >>> 0.6744739152943241
2774 |
2775 | ```
2776 | ## Свойства numerator и denominator, as_integer_ratio()
2777 | ```python
2778 | from fractions import Fraction
2779 |
2780 | num = Fraction('5/16')
2781 |
2782 | print('Числитель дроби равен:', num.numerator)
2783 | print('Знаменатель дроби равен:', num.denominator)
2784 | >>> Числитель дроби равен: 5
2785 | >>> Знаменатель дроби равен: 16
2786 |
2787 | ```
2788 | Метод `as_integer_ratio() `возвращает кортеж, состоящий из числителя и знаменателя данного Fraction числа:
2789 | ```python
2790 | from fractions import Fraction
2791 |
2792 | num = Fraction('-5/16')
2793 |
2794 | print(num.as_integer_ratio())
2795 | >>> (-5, 16)
2796 |
2797 | ```
2798 | ## Метод limit_denominator()
2799 | Метод `limit_denominator() `возвращает самую близкую к данному числу рациональную дробь, чей знаменатель не превосходит переданного аргумента:
2800 | ```python
2801 | from fractions import Fraction
2802 |
2803 | num = (Fraction("0.83485"))
2804 |
2805 | for d in [1, 5, 50, 90, 100, 500, 1000000]:
2806 | limited = num.limit_denominator(d)
2807 | print(limited)
2808 | >>> 1
2809 | >>> 4/5
2810 | >>> 5/6
2811 | >>> 71/85
2812 | >>> 81/97
2813 | >>> 369/442
2814 | >>> 16697/20000
2815 |
2816 | ```
2817 | ## Комплексные числа: введение
2818 | ```
2819 | Рассмотрим квадрат произвольного вещественного числа:
2820 | - 2*2=4
2821 | - (−2)*(−2)=4
2822 | - 0*0=0
2823 | - 0.1*0.1=0.01
2824 | Результат всегда неотрицательное число. Действительно, пусть a – произвольное вещественное число. Тогда a*a=a^2≥0. Таким образом, на множестве вещественных чисел, перемножая два одинаковых числа мы всегда получаем неотрицательное число (большее, либо равное нулю).
2825 |
2826 | Представим, что существует число i (не являющееся вещественным), такое, что i*i=i^2=−1. Будет ли такое обозначение полезным? Оказывается, да! Такие числа в математике называются мнимыми и обозначают их буквой i, от слова imaginary (мнимый, воображаемый). Итак, получаем:
2827 | i^2=-1, отсюда i = √(-1)
2828 |
2829 | Мнимая единица i обладает интересным свойством: каждый раз при умножении на i она "циклически" проходит через 4 различных значения:
2830 | 1*i=i
2831 | i*i=-1
2832 | -1*i=-1
2833 | -i*i=1
2834 | ```
2835 |
2836 | ## Комплексные числа в математике
2837 | Комплексное число – комбинация вещественного и мнимого числа. Таким образом, число вида a+bi, где a, b – вещественные числа, называется комплексным числом.
2838 |
2839 | Модулем комплексного числа z=a+bi называется вещественное число, равное:
2840 | |z|=√(a^2+b^2)
2841 |
2842 | Число zˉ=a−bi называется сопряженным к числу z=a+bi. Произведение двух сопряженных чисел является вещественным числом.
2843 |
2844 | ## Комплексные числа в Python
2845 | Для работы с комплексными числами (тип complex) не нужно подключать какой-либо модуль в отличие от типов Decimal и Fraction.
2846 | В языке Python есть возможность работать с комплексными числами. Общая форма представления комплексного числа следующая: real + imag j, где:
2847 | - real – вещественная часть комплексного числа
2848 | - imag – мнимая часть комплексного числа, которая завершается символом j или J.
2849 |
2850 | ```python
2851 | z1 = 5 + 7j
2852 | z2 = 1j
2853 | z3 = -3 + 5J
2854 | z4 = 1.5 + 3.2j
2855 |
2856 | print(z1, z2, z3, z4, sep='\n')
2857 | print(type(z1))
2858 | >>> (5+7j)
2859 | >>> 1j
2860 | >>> (-3+5j)
2861 | >>> (1.5+3.2j)
2862 | >>>
2863 |
2864 | ```
2865 | ## Создание комплексных чисел
2866 | Комплексные числа можно создать с помощью литерала, как выше, а можно с помощью функции `complex()`, которая принимает два аргумента: вещественную и мнимую часть числа, либо строковое представление числа.
2867 | ```python
2868 | z1 = -3 + 2j # создание на основе литерала
2869 | z2 = complex(6, -8) # z2 = 6 - 8j
2870 | z3 = complex(0, 2.5) # z3 = 2.5j
2871 | z4 = complex(5, 0) # z4 = 5 + 0j
2872 | z5 = complex('3+4j') # создание на основе строки
2873 |
2874 | print(z1, z2, z3, z4, z5, sep='\n')
2875 | >>> (-3+2j)
2876 | >>> (6-8j)
2877 | >>> 2.5j
2878 | >>> (5+0j)
2879 | >>> (3+4j)
2880 |
2881 | ```
2882 | ## Арифметические операции над комплексными числами
2883 | ```python
2884 | z1 = 1 + 3j
2885 | z2 = -3 + 2j
2886 |
2887 | print('z1 + z2 =', z1 + z2)
2888 | print('z1 - z2 =', z1 - z2)
2889 | print('z1 * z2 =', z1 * z2)
2890 | print('z1 / z2 =', z1 / z2)
2891 | print('z1^20 =', z1**20)
2892 | >>> z1 + z2 = (-2+5j)
2893 | >>> z1 - z2 = (4+1j)
2894 | >>> z1 * z2 = (-9-7j)
2895 | >>> z1 / z2 = (0.23076923076923078-0.8461538461538461j)
2896 | >>> z1^20 = (9884965888-1512431616j)
2897 | ```
2898 | Мы также можем совершать арифметические операции над complex и целыми числами (миксовать complex, int, float).
2899 |
2900 | ## Методы и свойства комплексных чисел
2901 | ```python
2902 | z = 3+4j
2903 |
2904 | print('Действительная часть =', z.real)
2905 | print('Мнимая часть =', z.imag)
2906 | >>> Действительная часть = 3.0
2907 | >>> Мнимая часть = 4.0
2908 |
2909 | ```
2910 | Для нахождения сопряженного комплексного числа можно использовать метод `conjugate()`:
2911 | ```python
2912 | z = 3+4j
2913 | print('Сопряженное число =', z.conjugate())
2914 | >>> Сопряженное число = (3-4j)
2915 |
2916 | ```
2917 | Для нахождения модуля комплексного числа используется встроенная функция `abs()`:
2918 | ```python
2919 | z = 3+4j
2920 | print('Модуль числа =', abs(z))
2921 | >>> Модуль числа = 5.0
2922 |
2923 | ```
2924 | ## cmath
2925 | Встроенный модуль math работает с вещественными числами. Для работы с комплексными числами есть модуль cmath. Модуль cmath включает дополнительные функции для использования комплексных чисел.
2926 | ```python
2927 | import cmath
2928 |
2929 | z = 2+3j
2930 | print(cmath.phase(z)) # полярный угол
2931 | print(cmath.polar(z)) # полярные координаты
2932 | >>> 0.982793723247329
2933 | >>> (3.605551275463989, 0.982793723247329)
2934 | ```
2935 | Модуль cmath содержит следующие категории функций:
2936 | - Экспоненциальные и логарифмические функции
2937 | - Квадратные корни
2938 | - Тригонометрические функции и их обратные
2939 | - Гиперболические функции и их обратные
2940 |
2941 | # Модуль turtle
2942 | ## Введение в turtle
2943 | Подключение модуля:
2944 | ```python
2945 | import turtle
2946 |
2947 | ```
2948 | В результате команды `turtle.showturtle()` появляется графическое окно с черепашкой. Черепашка первоначально расположена в центре графического окна, "холста". Выглядит она как стрелка с острием на месте головы. Если дать черепашке команду двигаться вперед, она переместится в направлении, указываемом стрелкой. По умолчанию на старте черепашка смотрит на восток.
2949 |
2950 | ## Рисование отрезков прямой
2951 | Для перемещения черепашки вперед на n пикселей применяется команда `turtle.forward(n)`.
2952 | Для перемещения черепашки назад на n пикселей применяется команда `turtle.backward(n)`.
2953 |
2954 | ## Поворот черепашки
2955 | Команда `turtle.right(angle) `поворачивает черепашку вправо на angle градусов.
2956 | Команда `turtle.left(angle)` поворачивает черепашку влево на angle градусов.
2957 | Команда `turtle.setheading(angle)` применяется для установки углового направления черепашки с заданным углом. В качестве аргумента нужно указать желаемый угол.
2958 | Чтобы получить текущее угловое направление черепашки используется команда `turtle.heading()`.
2959 |
2960 | ## Изменение внешнего вида черепашки
2961 | По умолчанию черепашка выглядит как стрелочка, но возможен и другой внешний вид. Для его изменения используют команду `turtle.shape(shape_name).` Команда принимает в качестве аргумента строковое название фигуры, определяющей форму черепашки. Доступные фигуры:
2962 | - square (квадрат)
2963 | - arrow (стрелка)
2964 | - circle (круг)
2965 | - turtle (черепашка)
2966 | - triangle (треугольник)
2967 | - classic (классическая стрелка)
2968 |
2969 | При необходимости можно использовать собственные рисунки для создания внешнего вида черепашки:
2970 | ```python
2971 | import turtle
2972 |
2973 | turtle.Screen().addshape('rocketship.gif') # регистрируем изображение
2974 | turtle.shape('rocketship.gif') # устанавливаем изображение
2975 |
2976 |
2977 | for _ in range(4):
2978 | turtle.forward(150)
2979 | turtle.left(90)
2980 |
2981 | ```
2982 | ## Поднятие и опускание пера
2983 | Команда `turtle.penup() `поднимает перо, а команда `turtle.pendown()` - опускает. Когда перо поднято, черепашка перемещается не оставляя линии. Когда перо опущено, черепашка во время перемещения чертит линию. По умолчанию перо опущено.
2984 |
2985 | ## Рисование кругов и точек
2986 | Чтобы черепашка нарисовала круг, можно применить команду `turtle.circle(radius)`. Такая команда рисует круг заданного в виде аргумента в пикселях радиуса.
2987 | Команда `turtle.dot()` применяется, чтобы черепашка нарисовала точку.
2988 | ## Изменение размера пера
2989 | Для изменения ширины пера черепашки в пикселях можно применить команду `turtle.pensize(size)`. Аргумент команды – целое число, задает ширину пера.
2990 |
2991 | ## Изменение цвета рисунка
2992 | Для изменения цвета рисунка можно применить команду `turtle.pencolor(color)`. Аргумент команды – строковое представление названия цвета.
2993 | Пример: `turtle.pencolor('red')`.
2994 | Наиболее распространённые цвета:
2995 | - red (красный)
2996 | - green (зеленый)
2997 | - bluе (синий)
2998 | - yellow (желтый)
2999 | - cyan (сине-зелёный)
3000 |
3001 | Команда `turtle.pencolor(color)` позволяет работать не только с предопределенными названиями цветов, но и с цветами, заданными в формате RGB (Red Green Blue). В качестве аргумента команды `turtle.pencolor(r, g, b)` можно использовать либо кортеж из 3 чисел (r, g, b), либо просто три числа r, g, b. В Python 3 для того, чтобы использовать цвет в формате RGB, нужно предварительно установить значение colormode в 255, для этого нужно использовать команду `turtle.Screen().colormode(255).`
3002 |
3003 | ## Изменение цвета фона
3004 | Для изменения фонового цвета графического окна можно применить команду `turtle.Screen().bgcolor(color)`. В этом случае тоже можно использовать цвета с предопределенными названиями или задать цвет в RGB формате.
3005 |
3006 | Мы также можем установить фоновое изображение с помощью команды `turtle.Screen().bgpic('picture.png')`.
3007 |
3008 | ## Создание штампа
3009 | С помощью команды `turtle.stamp()` можно оставить штамп черепашки. Использование команды `turtle.stamp()` производит тот же эффект, что и команда `turtle.dot([radius])`, но оставляет отметку в форме черепашки.
3010 |
3011 | ## Возвращение экрана в исходное состояние
3012 | Команда `turtle.clear()` стирает все рисунки в графическом окне. Но не меняет положение черепашки, цвет рисунка и цвет фона графического окна.
3013 | Команда `turtle.reset()` стирает все рисунки, имеющиеся в графическом окне, задает черный цвет рисунка и возвращает черепашку в исходное положение в центре экрана. Эта команда не переустанавливает цвет фона графического окна.
3014 | Команда `turtle.clearscreen()` стирает все рисунки в графическом окне, меняет цвет рисунка на черный, а цвет фона на белый, и возвращает черепашку в исходное положение в центре графического окна.
3015 |
3016 | ## Размер окна
3017 | Для установления размера графического окна можно применить команду `turtle.Screen().setup(width, height)`. Аргументы команды – ширина и высота (в пикселях).
3018 |
3019 | ## Перемещение черепашки в заданную позицию
3020 | 
3021 | Для перемещения черепашки в конкретную позицию в графическом окне применяется команда `turtle.goto(x, y)`. Аргументами служат координаты целевой позиции. Если перо черепашки опущено вниз (по умолчанию оно опущено), то будет начерчена линия.
3022 |
3023 | Команды `turtle.setposition(x, y)` и `turtle.setpos(x, y)` аналогичны команде `turtle.goto(x, y)`. Все три команды перемещают черепашку в заданную позицию.
3024 |
3025 | ## Получение текущей позиции черепашки
3026 | Команда `turtle.pos()` возвращает кортеж с x и y координатами черепашки. Команда `turtle.position()` аналогична команде `turtle.pos()`. Обе эти команды возвращают кортеж с x и y координатами черепашки.
3027 | Для получения только координаты x черепашки служит команда `turtle.xcor()`, а для получения координаты y - команда `turtle.ycor()`.
3028 |
3029 | ## Сокрытие черепашки
3030 | Когда не нужно, чтобы черепашка отображалась на экране, применяется команда `turtle.hideturtle()`, которая ее прячет. Эта команда не изменяет процесс создания графического изображения, она просто скрывает значок черепашки. Когда требуется снова вывести черепашку на экран, применяется команда `turtle.showturtle()`.
3031 |
3032 | ## Управление скоростью анимации черепахи
3033 | Для изменения скорости движения черепашки можно применить команду `turtle.speed(speed)`. Аргумент команды скорость – число в диапазоне от 0 до 10. Если указать 0, то черепашка будет делать все свои перемещения мгновенно (анимация отключена).
3034 |
3035 | ## Вывод текста в графическое окно
3036 | Для вывода текста в графическое окно применяется команда `turtle.write(string)`. Аргумент этой команды — строка текста, которую требуется вывести на экран. Левый нижний угол первого символа выведенного текста будет расположен в точке с координатами черепашки.
3037 |
3038 | Аргументы команды `write(args)`:
3039 | - arg – текст, который нужно вывести
3040 | - move – указывает будет ли двигаться черепашка по мере рисования надписи (по умолчанию значение False)
3041 | - align – служит для выравнивания надписи относительно черепашки, может принимать три строковых значения right, center, left (по умолчанию значению right)
3042 | - font – кортеж из трех значений: (название шрифта, размер шрифта, тип начертания). В качестве начертания можно использовать строковые значения: normal — обычный, bold — полужирный, italic — курсив, или объединить два последних, тогда текст будет напечатан полужирным курсивом.
3043 |
3044 | Пример:
3045 | ```python
3046 | import turtle
3047 | turtle.write('Приветик)', move=True, align='left', font=('Times New Roman', 25, 'normal'))
3048 | ```
3049 | Вывод:
3050 | 
3051 |
3052 | ## Заполнение геометрических фигур
3053 | Для заполнения геометрической фигуры цветом используется команда `turtle.begin_fill()`, причем она применяется до начертания фигуры, а после завершения начертания используется команда `turtle.end_fill()` и геометрическая фигура заполняется текущим цветом заливки.
3054 |
3055 | Пример:
3056 | ```python
3057 | import turtle
3058 |
3059 | turtle.hideturtle()
3060 | turtle.begin_fill() # включаем заливку
3061 | turtle.circle(80)
3062 | turtle.end_fill() # выключаем заливку
3063 | ```
3064 | Вывод:
3065 | 
3066 |
3067 | Цвет заливки можно изменить при помощи команды `turtle.fillcolor(color / r, g, b)`. Аргумент команды — название цвета в виде строкового литерала, либо значения трех компонентов RGB.
3068 |
3069 | ## Создание нескольких черепашек
3070 | Можно работать сразу с несколькими черепашками. Для этого надо создать несколько переменных, содержащих экземпляры класса Turtle.
3071 |
3072 | Пример:
3073 | ```python
3074 | import turtle
3075 | from random import randrange
3076 |
3077 | def move_turtles(turtles, dist, angle):
3078 | for turtle in turtles: # все черепашки из списка делают одни и те же действия
3079 | turtle.forward(dist)
3080 | turtle.right(angle)
3081 |
3082 |
3083 | turtles = [] # список черепашек
3084 | head = 0
3085 | num_turtles = 10 # количество череашек
3086 | for i in range(num_turtles):
3087 | turt = turtle.Turtle() # создаем черепашку и устанавливаем ее свойства
3088 | turt.setheading(head)
3089 | turt.pensize(2)
3090 | turt.color(randrange(256), randrange(256), randrange(256))
3091 | turt.speed(5)
3092 | turt.tracer(25, 0)
3093 | turtles.append(turt) # добавляем черепашку в список
3094 | head = head + 360/num_turtles
3095 |
3096 | for i in range(70):
3097 | move_turtles(turtles, 10, i)
3098 |
3099 | ```
3100 | Вывод:
3101 | 
3102 |
3103 | Команда `turtle.tracer(n, delay)` включает/выключает анимацию черепашки и устанавливает задержку для обновления рисунков. Может использоваться для ускорения рисования сложной графики.
3104 |
3105 | ## Отслеживание нажатия клавиш
3106 | Черепашья графика позволяет отслеживать происходящие события, такие как нажатия клавиш клавиатуры, перемещение мышки или нажатие на мышку. Изначально программа никак не реагирует на эти события и чтобы это поведение изменить необходимо привязать функции обратного вызова к событиям. Для этого существуют специальные команды. Для отслеживания нажатия клавиш клавиатуры используется команда `turtle.Screen().onkey(fun, key)`, которая связывает функцию обратного вызова fun с событием нажатия клавиши key.
3107 | Для отслеживания событий также необходимо установить фокус на экран черепашки с помощью команды `turtle.Screen().listen()`.
3108 | Пример:
3109 | ```python
3110 | import turtle
3111 |
3112 | def move_up(): # функция обратного вызова
3113 | x, y = turtle.pos()
3114 | turtle.setposition(x, y + 5)
3115 |
3116 | def move_down(): # функция обратного вызова
3117 | x, y = turtle.pos()
3118 | turtle.setposition(x, y - 5)
3119 |
3120 | def move_left(): # функция обратного вызова
3121 | x, y = turtle.pos()
3122 | turtle.setposition(x - 5, y)
3123 |
3124 | def move_right(): # функция обратного вызова
3125 | x, y = turtle.pos()
3126 | turtle.setposition(x + 5, y)
3127 |
3128 | turtle.showturtle() # отображаем черепашку
3129 | turtle.pensize(3) # устанавливаем размер пера
3130 | turtle.shape('turtle')
3131 | turtle.Screen().listen() # устанавливаем фокус на экран черепашки
3132 |
3133 | turtle.Screen().onkey(move_up, 'Up') # регистрируем функцию на нажатие клавиши наверх
3134 | turtle.Screen().onkey(move_down, 'Down') # регистрируем функцию на нажатие клавиши вниз
3135 | turtle.Screen().onkey(move_left, 'Left') # регистрируем функцию на нажатие клавиши налево
3136 | turtle.Screen().onkey(move_right, 'Right') # регистрируем функцию на нажатие клавиши направо
3137 |
3138 | ```
3139 | ## Отслеживание нажатия мыши
3140 | Аналогичным образом можно отслеживать нажатие на мышку. Для отслеживания нажатия мыши используется команда `turtle.Screen().onclick(fun)`, которая связывает функцию обратного вызова fun с событием нажатия левой кнопки мыши.
3141 | Пример:
3142 | ```python
3143 | import turtle
3144 | from random import randrange
3145 |
3146 | def random_color():
3147 | return randrange(256), randrange(256), randrange(256)
3148 |
3149 | def draw_circle(x, y, r):
3150 | turtle.penup()
3151 | turtle.goto(x, y - r)
3152 | turtle.pendown()
3153 | color = random_color()
3154 | turtle.pencolor(color)
3155 | turtle.fillcolor(color)
3156 | turtle.begin_fill()
3157 | turtle.circle(r)
3158 | turtle.end_fill()
3159 | turtle.speed(0)
3160 |
3161 | def left_mouse_click(x, y):
3162 | draw_circle(x, y, 10)
3163 |
3164 | turtle.hideturtle()
3165 |
3166 | turtle.Screen().onclick(left_mouse_click)
3167 | turtle.Screen().listen()
3168 |
3169 | ```
3170 | # Функции
3171 | ## Функции без параметров
3172 | Именование функций
3173 | Python и тут требует соблюдения тех же правил, что при именовании переменных:
3174 | - в имени функции используются только латинские буквы a-z, A-Z, цифры и символ нижнего подчеркивания (_)
3175 | - имя функции не может начинаться с цифры
3176 | - имя функции по возможности должно отражать ее назначение
3177 | - символы верхнего и нижнего регистра различаются.
3178 | Объявление функции:
3179 | ```python
3180 | def название_функции():
3181 | блок кода
3182 |
3183 | pass # ничего не делает, используется как заглушка.
3184 | ```
3185 | Вызов функции:
3186 | ```python
3187 | название_функции()
3188 | ```
3189 | Объявление функции должно предшествовать ее вызову.
3190 |
3191 | ## Функции с параметрами
3192 | Объявление функции с параметрами:
3193 | ```python
3194 | def название_функции(параметры):
3195 | блок кода
3196 | ```
3197 | При вызове функции мы обязаны использовать столько аргументов, сколько объявлено в функции.
3198 | Пример:
3199 | ```python
3200 | def draw(c):
3201 | for i in range(c):
3202 | print('*' * 10)
3203 |
3204 | draw(10)
3205 | >>> **********
3206 | >>> **********
3207 | >>> **********
3208 | >>> **********
3209 | >>> **********
3210 | >>> **********
3211 | >>> **********
3212 | >>> **********
3213 | >>> **********
3214 | >>> **********
3215 |
3216 | ```
3217 | ## Глобальные, нелокальные и локальные переменные
3218 | Локальными называются переменные, объявленные внутри функции и доступные только ей самой. Программный код за пределами функции к ним доступа не имеет.
3219 | ```python
3220 | def print_paris():
3221 | s = 'I love Paris'
3222 | print(s)
3223 |
3224 | def print_london():
3225 | s = 'I love London'
3226 | print(s)
3227 |
3228 | s = 'I love Moscow'
3229 | print_paris()
3230 | print_london()
3231 | print(s)
3232 | >>> I love Paris
3233 | >>> I love London
3234 | >>> I love Moscow
3235 |
3236 | ```
3237 | Глобальными называются переменные, объявленные в основной программе и доступные как программе, так и всем ее функциям.
3238 | Если нужно, чтобы инструкция внутри функции присваивала значение глобальной переменной, то требуется дополнительный шаг. В этом случае глобальная переменная должна быть объявлена внутри функции. Благодаря `global `можно изменять глобальную переменную в функции.
3239 | ```python
3240 | def print_texas():
3241 | global birds
3242 | birds = 5000
3243 | print('В Техасе обитает', birds, 'птиц.')
3244 |
3245 | def print_california():
3246 | print('В Калифорнии обитает', birds, 'птиц.')
3247 |
3248 | print_texas()
3249 | print_california()
3250 | >>> В Техасе обитает 5000 птиц.
3251 | >>> В Калифорнии обитает 5000 птиц.
3252 | ```
3253 | В следующем коде мы работаем с глобальной переменной в функции:
3254 | ```python
3255 | x = 5
3256 |
3257 | def add():
3258 | global x
3259 | x = 3
3260 | x = x + 5
3261 | print(x)
3262 |
3263 | add()
3264 | print(x)
3265 | ```
3266 | Код выведет 8 8, так как мы использовали `global x`, а значит функция будет изменять глобальную переменную.
3267 |
3268 | Также есть `nonlocal` переменные, они видны внутри вложенной функции, но относятся к переменным из внешней функции (не глобальной).
3269 | Если во вложенной функции используется `nonlocal`, то переменной должно быть присвоено значение во внешней функции до этого — иначе будет ошибка:
3270 | ```python
3271 | def main():
3272 | def print_number():
3273 | nonlocal number # ошибка
3274 | number = 5
3275 | print(number)
3276 |
3277 | print_number()
3278 |
3279 |
3280 | main()
3281 |
3282 | ```
3283 | ## Функции с возвратом значения
3284 | Некоторые команды в Python возвращают что-то, например, `len("Бургер") `вернёт 6.
3285 | Есть команды, которые ничего не возвращают, например, `del a[2] `просто удаляет элемент списка.
3286 | Для возврата значения используют `return значение `в конце тела функции. Все команды написанные после `return `в функции не будут выполнятся.
3287 | Пример:
3288 | ```python
3289 | def square(x):
3290 | return x**2
3291 |
3292 | print(square(2))
3293 | >>> 4
3294 | ```
3295 | Код выводит квадрат числа 2
3296 |
3297 | Также можно возвращать `True` или `False`.
3298 | Пример:
3299 | ```python
3300 | def divide(x):
3301 | if x % 2 == 0:
3302 | return True
3303 |
3304 | if divide(2):
3305 | print('Число делится на 2')
3306 | else:
3307 | print('Число не делится на 2')
3308 |
3309 | ```
3310 | Также можно возвращать несколько значений:
3311 | ```python
3312 | def sqr(x, y):
3313 | return x**2, y**2
3314 |
3315 | print(sqr(2, 4))
3316 | >>> (4, 16)
3317 |
3318 | ```
3319 | ## Позиционные и именованные аргументы
3320 | Все ранее написанные нами функции имели позиционные аргументы. Такие аргументы передаются без указания имен. Они называются позиционными, потому что именно по позиции, расположению аргумента, функция понимает, какому параметру он соответствует.
3321 | ```python
3322 | def diff(x, y):
3323 | return x - y
3324 |
3325 |
3326 | res = diff(10, 3) # используем позиционные аргументы
3327 | print(res)
3328 | >>> 7
3329 | ```
3330 | При вызове функции `diff()` первому параметру x будет соответствовать первый переданный аргумент, 10, а второму параметру y — второй аргумент, 3.
3331 |
3332 | Аргументы, передаваемые с именами, называются именованными. При вызове функции можно использовать имена параметров из ее определения.
3333 | ```python
3334 | def diff(x, y):
3335 | return x - y
3336 |
3337 |
3338 | res = diff(y=3, x=10) # используем именованные аргументы
3339 | print(res)
3340 | >>> 7
3341 | ```
3342 | Такой код по-прежнему выведет число 7. При вызове функции `diff()` мы явно указываем, что параметру x соответствует аргумент 10, а параметру y - аргумент 3.
3343 |
3344 | Комбинировать позиционные и именованные аргументы можно, но позиционные значения должны быть указаны до любых именованных.
3345 | ```python
3346 | res = diff(10, y=3) # используем позиционный и именованный аргумент
3347 | ```
3348 | Но:
3349 | ```python
3350 | res = diff(x=10, 3) # используем позиционный и именованный аргумент
3351 | ```
3352 | Приводит к возникновению ошибки `SyntaxError: positional argument follows keyword argument.`
3353 |
3354 | ## Необязательные аргументы
3355 | Например, нам нужна функция которая рисует круг с радиусом radius при указании аргумента radius. Если его не указать, radius будет выставлено значение 10. Вот так это можно реализовать:
3356 | ```python
3357 | def draw_circle(radius=10):
3358 | print(f"Радиус круга: {radius}")
3359 |
3360 |
3361 | draw_circle()
3362 | draw_circle(100)
3363 | >>> Радиус круга: 10
3364 | >>> Радиус круга: 100
3365 |
3366 | ```
3367 | ## Изменяемые типы в качестве значений по умолчанию
3368 | ```python
3369 | def append(element, seq=[]):
3370 | seq.append(element)
3371 | return seq
3372 |
3373 |
3374 | print(append(100, []))
3375 | print(append(238, []))
3376 |
3377 | print(append(100))
3378 | print(append(238))
3379 | >>> [100]
3380 | >>> [238]
3381 | >>> [100]
3382 | >>> [100, 238]
3383 | ```
3384 | Почему `append(238)` выводит не `[238]`, а `[100, 238]`? Значение по умолчанию для параметра создается единожды при определении функции (обычно при загрузке модуля) и становится атрибутом (свойством) функции. Поэтому, если значение по умолчанию изменяемый объект, то его изменение повлияет на каждый следующий вызов функции. Вместо этого используйте такой код:
3385 | ```python
3386 | def append(element, seq=None):
3387 | if seq is None:
3388 | seq = []
3389 | seq.append(element)
3390 | return seq
3391 |
3392 | ```
3393 | Чтобы посмотреть значения по умолчанию, можно использовать атрибут `__defaults__`:
3394 | ```python
3395 | def append(element, seq=[]):
3396 | seq.append(element)
3397 | return seq
3398 |
3399 | print('Значение по умолчанию', append.__defaults__)
3400 | print(append(10))
3401 | print('Значение по умолчанию', append.__defaults__)
3402 | print(append(5))
3403 | print('Значение по умолчанию', append.__defaults__)
3404 | print(append(1))
3405 | print('Значение по умолчанию', append.__defaults__)
3406 | >>> Значение по умолчанию ([],)
3407 | >>> [10]
3408 | >>> Значение по умолчанию ([10],)
3409 | >>> [10, 5]
3410 | >>> Значение по умолчанию ([10, 5],)
3411 | >>> [10, 5, 1]
3412 | >>> Значение по умолчанию ([10, 5, 1],)
3413 |
3414 | ```
3415 | ## Переменное количество аргументов (*args, **kwargs)
3416 | Функция может принимать столько аргументов, сколько ей передали:
3417 | ```python
3418 | def my_func(*args):
3419 | print(type(args))
3420 | print(args)
3421 |
3422 |
3423 | my_func()
3424 | my_func(1, 2, 3)
3425 | my_func('a', 'b')
3426 | >>>
3427 | >>> ()
3428 | >>>
3429 | >>> (1, 2, 3)
3430 | >>>
3431 | >>> ('a', 'b')
3432 | ```
3433 | Звездочка в определении функции означает, что переменная (параметр) args получит в виде кортежа все аргументы, переданные в функцию при ее вызове от текущей позиции и до конца. *args нужно указывать после всех аргументов:
3434 | ```python
3435 | def my_func(num, *args):
3436 | print(args)
3437 | print(num)
3438 |
3439 |
3440 | my_func(17, 'Python', 2, 'C#')
3441 | >>> ('Python', 2, 'C#')
3442 | >>> 17
3443 | ```
3444 | Помеченный звездочкой параметр *args нормально переживает и отсутствие аргументов, в то время как позиционные параметры всегда обязательны.
3445 |
3446 | После *args можно передавать и другие аргументы, однако передать их можно только как keyword-only:
3447 | ```python
3448 | def string_multiplication(*args, times):
3449 | for i in args:
3450 | yield str(i) * times
3451 |
3452 |
3453 | print(*string_multiplication(1, 2, times=5))
3454 | >>> 11111 22222
3455 |
3456 | ```
3457 | ## Передача аргументов в форме списка и кортежа
3458 | (*args):
3459 | ```python
3460 | def my_sum(*args):
3461 | return sum(args) # args - это кортеж
3462 |
3463 |
3464 | print(my_sum(*[1, 2, 3, 4, 5])) # распаковка списка
3465 | print(my_sum(*(1, 2, 3))) # распаковка кортежа
3466 | >>> 15
3467 | >>> 6
3468 |
3469 | ```
3470 | (**kwargs):
3471 | ```python
3472 | def my_func(**kwargs):
3473 | print(type(kwargs))
3474 | print(kwargs)
3475 |
3476 |
3477 | info = {"name": "Timur", "age": "28", "job": "teacher"}
3478 | my_func(**info)
3479 | >>>
3480 | >>> {'name': 'Timur', 'age': '28', 'job': 'teacher'}
3481 |
3482 | ```
3483 | ## Получение именованных аргументов в виде словаря
3484 | Позиционные аргументы можно получать в виде *args, причём произвольное их количество. Такая возможность существует и для именованных аргументов. Только именованные аргументы получаются в виде словаря, что позволяет сохранить имена аргументов в ключах.
3485 | ```python
3486 | def my_func(**kwargs):
3487 | print(type(kwargs))
3488 | print(kwargs)
3489 |
3490 |
3491 | my_func(a=1, b=2)
3492 | my_func(name="Timur", job="Teacher")
3493 | >>>
3494 | >>> {'a': 1, 'b': 2}
3495 | >>>
3496 | >>> {'name': 'Timur', 'job': 'Teacher'}
3497 |
3498 | ```
3499 | ## Keyword-only и positional-only аргументы
3500 | В Python 3 добавили возможность пометить именованные аргументы функции так, чтобы вызвать функцию можно было, только передав эти аргументы по именам. Такие аргументы называются keyword-only и их нельзя передать в функцию в виде позиционных.
3501 | ```python
3502 | def make_circle(x, y, radius, *, line_width=1, fill=True):
3503 | pass
3504 |
3505 |
3506 | make_circle(10, 20, 10, line_width=2, fill=False)
3507 | ```
3508 | Здесь * выступает разделителем: отделяет обычные аргументы (их можно указывать по имени и позиционно) от строго именованных. Справа – строго именованные.
3509 |
3510 | Существуют и positional-only аргументы, слева от разделителя / - только позиционные аргументы:
3511 | ```python
3512 | def make_circle(x, y, radius, /, line_width, fill):
3513 | pass
3514 |
3515 |
3516 | make_circle(1, 1, 3, line_width=0.1, fill=False)
3517 |
3518 | ```
3519 | Удобно комбинировать их:
3520 | ```python
3521 | def func(a, /, b, *, c):
3522 | pass
3523 |
3524 |
3525 | func(1, b=2, c=3)
3526 | func(1, 2, c=3)
3527 |
3528 | ```
3529 | ## Функции как объекты
3530 | Встроенные функции или методы Python:
3531 | ```python
3532 | print(type(print))
3533 | print(type(sum))
3534 | print(type(abs))
3535 | >>>
3536 | >>>
3537 | >>>
3538 |
3539 | ```
3540 | Тип обычных функций:
3541 | ```python
3542 | def hello():
3543 | print('Hello from function')
3544 |
3545 |
3546 | print(type(hello))
3547 | >>>
3548 |
3549 | ```
3550 | Мы можем назначить переменной функцию:
3551 | ```python
3552 | печать = print
3553 | печать("Hello World!")
3554 | >>> Hello World!
3555 |
3556 | ```
3557 | Выполнение функции, введённой с клавиатуры:
3558 | ```python
3559 | def start():
3560 | # тело функции start
3561 | pass
3562 |
3563 |
3564 | def stop():
3565 | # тело функции stop
3566 | pass
3567 |
3568 |
3569 | def pause():
3570 | # тело функции pause
3571 | pass
3572 |
3573 |
3574 | commands = {'start': start, 'stop': stop, 'pause': pause} # словарь соответствия команда → функция
3575 | command = input() # считываем название команды
3576 | commands[command]() # вызываем нужную функцию через словарь по ключу
3577 |
3578 | ```
3579 | ## Функции в качестве аргументов других функций
3580 | ```python
3581 | def pick(f):
3582 | f()
3583 |
3584 |
3585 | def first():
3586 | print("Первая функция")
3587 |
3588 |
3589 | def second():
3590 | print("Вторая функция")
3591 |
3592 |
3593 | pick(first)
3594 | >>> Первая функция
3595 |
3596 | ```
3597 | ## key в min(), max(), sort(), sorted()
3598 | Стандартно `min(), max(), sort(), sorted()` сравнивают сами элементы, однако можно указать key - ключ, по которому будут сравниваться аргументы. Важно, значением key должна быть функция, принимающая и возвращающая один аргумент.
3599 | Пример, сравнение по квадратам элементов:
3600 | ```python
3601 | def to_two(x):
3602 | return x**2
3603 |
3604 |
3605 | list = [-10, 0, 1]
3606 | list.sort(key=to_two)
3607 | print(list)
3608 | >>> [0, 1, -10] # так как [0, 1, 100] отсортирован по возрастанию (квадраты чисел)
3609 | ```
3610 | Можно использовать и встроенные функции:
3611 | ```python
3612 | list = [-10, 0, 1]
3613 | list.sort(key=abs)
3614 | print(list)
3615 | >>> [0, 1, -10] # так как [0, 1, 10] отсортирован по возрастанию (модули чисел)
3616 |
3617 | ```
3618 | ## Функции в качестве возвращаемых значений других функций (вложенные функции)
3619 | Можно использовать “вложенные” функции:
3620 | ```python
3621 | def main_function(a, b, c):
3622 | def function(x):
3623 | return a * b * c * x
3624 |
3625 | return function
3626 |
3627 |
3628 | print(main_function(1, 23, 12)(1))
3629 | >>> 276
3630 | ```
3631 | Пример использования:
3632 | ```python
3633 | def tracker(func_name):
3634 | def print_func_name(a):
3635 | print(func_name)
3636 | return a
3637 |
3638 | return print_func_name
3639 |
3640 |
3641 | print(max([1, 2, 3], key=tracker("max")))
3642 | print(min([1, 2, 3], key=tracker("min")))
3643 | ```
3644 | (Сначала вызывается трекер с именем функции, а затем функция внутри, возвращающая само число.)
3645 |
3646 | Второй пример:
3647 | ```python
3648 | def func(x):
3649 | def inner(y):
3650 | return y
3651 |
3652 | return inner
3653 |
3654 |
3655 | first = func(12) # в переменной first лежит функция inner, так как func вернула функцию, а не вызвала.
3656 | print(first(33))
3657 | >>> 33
3658 |
3659 | ```
3660 | ## Функции высшего порядка
3661 | Функции, которые принимают или/и возвращают другие функции, называются функциями высшего порядка.
3662 | ```python
3663 | def high_order_function(func): # функция высшего порядка, так как принимает функцию
3664 | return func(3)
3665 |
3666 |
3667 | def double(x): # обычная функция = функция первого порядка
3668 | return 2*x
3669 |
3670 |
3671 | def add_one(x): # обычная функция = функция первого порядка
3672 | return x + 1
3673 |
3674 | ```
3675 | ## map()
3676 | `map() `применяет функцию ко всем элементам последовательности:
3677 | ```python
3678 | def increase(num):
3679 | return num + 7
3680 |
3681 |
3682 | numbers = [1, 2, 3, 4, 5, 6]
3683 | new_numbers = map(increase, numbers)
3684 |
3685 | print(new_numbers)
3686 | >>>