Python для начинающих
الذهاب إلى القناة على Telegram
1 239
المشتركون
لا توجد بيانات24 ساعات
+17 أيام
-130 أيام
جاري تحميل البيانات...
القنوات المماثلة
لا توجد بيانات
هل تواجه مشاكل؟ يرجى تحديث الصفحة أو الاتصال بمدير الدعم الخاص بنا.
سحابة العلامات
الإشارات الواردة والصادرة
---
---
---
---
---
---
جذب المشتركين
يونيو '26
يونيو '26
+10
في 0 قنوات
مايو '26
+19
في 0 قنوات
Get PRO
أبريل '26
+21
في 0 قنوات
Get PRO
مارس '26
+36
في 0 قنوات
Get PRO
فبراير '26
+51
في 0 قنوات
Get PRO
يناير '26
+55
في 0 قنوات
Get PRO
ديسمبر '25
+60
في 0 قنوات
Get PRO
نوفمبر '25
+48
في 0 قنوات
Get PRO
أكتوبر '25
+16
في 0 قنوات
Get PRO
سبتمبر '25
+30
في 0 قنوات
Get PRO
أغسطس '25
+72
في 1 قنوات
Get PRO
يوليو '25
+19
في 1 قنوات
Get PRO
يونيو '25
+21
في 1 قنوات
Get PRO
مايو '25
+17
في 1 قنوات
Get PRO
أبريل '25
+20
في 1 قنوات
Get PRO
مارس '25
+23
في 1 قنوات
Get PRO
فبراير '25
+22
في 1 قنوات
Get PRO
يناير '25
+20
في 0 قنوات
Get PRO
ديسمبر '24
+22
في 1 قنوات
Get PRO
نوفمبر '24
+21
في 0 قنوات
Get PRO
أكتوبر '24
+24
في 1 قنوات
Get PRO
سبتمبر '24
+22
في 1 قنوات
Get PRO
أغسطس '24
+17
في 1 قنوات
Get PRO
يوليو '24
+30
في 1 قنوات
Get PRO
يونيو '24
+41
في 1 قنوات
Get PRO
مايو '24
+39
في 1 قنوات
Get PRO
أبريل '24
+23
في 1 قنوات
Get PRO
مارس '24
+35
في 1 قنوات
Get PRO
فبراير '24
+49
في 1 قنوات
Get PRO
يناير '24
+51
في 1 قنوات
Get PRO
ديسمبر '23
+52
في 2 قنوات
Get PRO
نوفمبر '23
+16
في 0 قنوات
Get PRO
أكتوبر '23
+31
في 1 قنوات
Get PRO
سبتمبر '23
+42
في 0 قنوات
Get PRO
أغسطس '23
+40
في 0 قنوات
Get PRO
يوليو '23
+28
في 0 قنوات
Get PRO
يونيو '23
+32
في 0 قنوات
Get PRO
مايو '23
+39
في 0 قنوات
Get PRO
أبريل '23
+40
في 0 قنوات
Get PRO
مارس '23
+125
في 0 قنوات
Get PRO
فبراير '23
+45
في 0 قنوات
Get PRO
يناير '23
+86
في 0 قنوات
Get PRO
ديسمبر '22
+168
في 0 قنوات
Get PRO
نوفمبر '22
+45
في 0 قنوات
Get PRO
أكتوبر '22
+94
في 0 قنوات
Get PRO
سبتمبر '22
+76
في 0 قنوات
Get PRO
أغسطس '22
+44
في 0 قنوات
Get PRO
يوليو '22
+96
في 0 قنوات
Get PRO
يونيو '22
+336
في 0 قنوات
| التاريخ | نمو المشتركين | الإشارات | القنوات | |
| 14 يونيو | 0 | |||
| 13 يونيو | +2 | |||
| 12 يونيو | 0 | |||
| 11 يونيو | +1 | |||
| 10 يونيو | +1 | |||
| 09 يونيو | +2 | |||
| 08 يونيو | 0 | |||
| 07 يونيو | 0 | |||
| 06 يونيو | +1 | |||
| 05 يونيو | 0 | |||
| 04 يونيو | +1 | |||
| 03 يونيو | 0 | |||
| 02 يونيو | +1 | |||
| 01 يونيو | +1 |
منشورات القناة
Использование
zip и enumerate в реальных задачах
Если вы ещё пишете циклы с кучей счётчиков и временных списков — велика вероятность, что zip и enumerate уже могут сделать ваш код проще и понятнее. Разберёмся на практических примерах.
---
### 1. enumerate: когда индекс нужен по делу
Типичный «новичковый» код:
items = ["apple", "banana", "orange"]
for i in range(len(items)):
print(i, items[i])
То же самое с enumerate в разы чище:
items = ["apple", "banana", "orange"]
for idx, item in enumerate(items):
print(idx, item)
Где это реально полезно?
#### Пример: нумерация строк в отчёте
lines = ["Login ok", "Wrong password", "Timeout", "Login ok"]
for line_no, line in enumerate(lines, start=1):
if "Wrong" in line:
print(f"Error on line {line_no}: {line}")
Флаг start=1 удобен, когда нужно человеческое (а не компьютерное) номерование.
---
### 2. zip: связываем несколько списков
zip шагает по нескольким итерируемым объектам одновременно:
names = ["Alice", "Bob", "Charlie"]
scores = [95, 82, 100]
for name, score in zip(names, scores):
print(f"{name}: {score}")
#### Пример: из двух списков — словарь
keys = ["host", "port", "use_ssl"]
values = ["example.com", 443, True]
config = dict(zip(keys, values))
print(config)
# {'host': 'example.com', 'port': 443, 'use_ssl': True}
---
### 3. zip + распаковка: транспонирование таблиц
Есть «таблица» как список строк:
rows = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
Хотим столбцы вместо строк:
cols = list(zip(*rows))
print(cols)
# [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Так можно, например, быстро посчитать максимум по каждому столбцу:
max_by_col = [max(col) for col in zip(*rows)]
print(max_by_col) # [7, 8, 9]
---
### 4. Комбо: enumerate + zip в задаче валидации
Допустим, нужно сравнить правильные ответы и ответы пользователя, а также вывести номер вопроса, где ошибка:
correct = ["A", "C", "B", "D"]
user = ["A", "B", "B", "D"]
for idx, (right, given) in enumerate(zip(correct, user), start=1):
if right != given:
print(f"Question {idx}: expected {right}, got {given}")
Здесь zip связывает пары ответов, а enumerate даёт нам номер вопроса — минимальный код, максимальная читабельность.
---
zip и enumerate — это не «фишечки для красоты», а инструменты, которые убирают лишний шум из кода. Как только начнёте видеть паттерны «мне нужен индекс» и «я иду по нескольким спискам сразу», эти функции станут вашей ежедневной привычкой.| 2 | Использование zip и enumerate в реальных задачах | 0 |
| 3 | Применение Counter и defaultdict в задачах подсчета данных
В Python есть два маленьких, но очень мощных инструмента для подсчета данных: Counter и defaultdict из модуля collections. Они экономят десятки строк кода и делают задачи подсчета почти «одноходовками».
---
## Counter: карманный статистик
Counter — это специализированный словарь для подсчета количества объектов. Внутри — обычный dict, но с удобным интерфейсом.
### Подсчет слов в тексте
from collections import Counter
text = "python is great and python is simple"
words = text.split()
word_counts = Counter(words)
print(word_counts)
print(word_counts.most_common(2)) # 2 самых частых слова
Что удобно:
- Counter сам инициализирует счетчики с нуля;
- метод most_common() сразу выдает топ-N элементов;
- можно складывать, вычитать, объединять счетчики как числа.
### Подсчет символов в строке
from collections import Counter
s = "abracadabra"
char_counts = Counter(s)
for char, count in char_counts.items():
print(char, count)
Ни одного if key not in dict — всё уже встроено.
---
## defaultdict: умный словарь с «значением по умолчанию»
Обычный словарь при обращении к несуществующему ключу вызывает ошибку. defaultdict сам создает значение, используя функцию, которую вы ему передадите.
### Группировка по ключу
Допустим, нужно сгруппировать студентов по курсу:
from collections import defaultdict
students = [
("Alice", 1),
("Bob", 2),
("Charlie", 1),
("Diana", 3),
]
by_course = defaultdict(list)
for name, course in students:
by_course[course].append(name)
print(by_course)
Без defaultdict пришлось бы каждый раз проверять, есть ли уже такой курс в словаре.
### Словарь-счетчик на defaultdict
defaultdict легко превращается в счетчик:
from collections import defaultdict
nums = [1, 2, 1, 3, 2, 1]
counts = defaultdict(int)
for n in nums:
counts[n] += 1
print(counts)
По сути, это «ручная версия» Counter, но зато более гибкая.
---
## Когда что использовать
- Нужен простой подсчет частот + топы, суммы, комбинации — Counter.
- Нужна сложная структура вроде «ключ → список», «ключ → множество» или нестандартная логика инициализации — defaultdict.
Оба инструмента отлично заходят в задачах обработки логов, текста, статистики, простых аналитических вычислений. Освоив их, вы перестанете писать однообразные шаблоны с проверками «а есть ли уже этот ключ» и сосредоточитесь на самой задаче. | 0 |
| 4 | Применение Counter и defaultdict в задачах подсчета данных | 0 |
| 5 | Мини-проекты с модулем turtle: обучаемся, рисуя
Если стандартный «учебник по Python» навевает зевоту, попробуем другой путь: будем учиться, рисуя. Модуль turtle входит в стандартную библиотеку Python, так что ничего дополнительно устанавливать не нужно — только открыть воображение.
---
### 1. Старт: первые линии
Минимальный пример — уже маленький проект:
import turtle
t = turtle.Turtle()
t.speed(3)
t.forward(100)
t.left(90)
t.forward(100)
turtle.done()
Ключевые команды:
- forward(n) — черепашка едет вперед на n пикселей
- left(angle) / right(angle) — поворот
- penup() / pendown() — перо вверх/вниз (рисовать или нет)
Этого уже достаточно, чтобы строить геометрию и тренировать циклы.
---
### 2. Мини-проект: генератор квадратных мандал
Потренируемся в циклах и функциях: нарисуем «мандалу» из квадратов.
import turtle
t = turtle.Turtle()
t.speed(0)
t.color("blue")
def draw_square(side):
for _ in range(4):
t.forward(side)
t.left(90)
for angle in range(0, 360, 10):
t.setheading(angle)
draw_square(100)
turtle.done()
Что мы закрепляем:
- функции (def draw_square)
- цикл for с шагом 10
- setheading(angle) — задаём абсолютный угол поворота
Измените шаг 10 на 5 или 20, длину стороны, цвет — наглядное «чувство кода» появляется очень быстро.
---
### 3. Мини-проект: случайный фейерверк
Теперь подключим случайность и познакомимся с модулем random.
import turtle
import random
t = turtle.Turtle()
t.speed(0)
turtle.bgcolor("black")
colors = ["red", "yellow", "orange", "cyan", "magenta", "white"]
def draw_burst(radius):
t.color(random.choice(colors))
for _ in range(12):
t.forward(radius)
t.backward(radius)
t.right(360 / 12)
for _ in range(20):
t.penup()
x = random.randint(-300, 300)
y = random.randint(-200, 200)
t.goto(x, y)
t.pendown()
draw_burst(random.randint(30, 80))
turtle.done()
Что осваиваем:
- random.randint и random.choice
- работу с координатами goto(x, y)
- фон окна bgcolor
---
### 4. Зачем это всё?
Такие мини-проекты:
- снимают «страх кода» — результат видно сразу;
- закрепляют основы: циклы, функции, модули, случайные числа;
- развивают интуицию: меняете одну строку — картина меняется заметно.
Попробуйте усложнить проекты: добавить управление с клавиатуры, анимацию движения, счётчик шагов. turtle — отличный полигон, чтобы сделать первые шаги в Python творческими, а не скучными. | 0 |
| 6 | Мини-проекты с модулем turtle: обучаемся, рисуя | 0 |
| 7 | Понимание работы контекстных менеджеров и создание своих с помощью contextlib
Если вы когда‑нибудь писали:
with open("data.txt") as f:
content = f.read()
то уже пользовались контекстным менеджером — просто, возможно, не задумывались об этом. Давайте разберёмся, что там происходит под капотом и как писать свои.
---
### Что такое контекстный менеджер?
Контекстный менеджер — это объект, который знает, что делать до и после блока with.
Под капотом Python делает примерно так:
manager = open("data.txt")
f = manager.__enter__()
try:
content = f.read()
finally:
manager.__exit__(None, None, None)
Два ключевых метода:
- __enter__(self) — подготавливает ресурс, возвращает объект, который попадёт в as.
- __exit__(self, exc_type, exc_val, exc_tb) — освобождает ресурс, даже если возникло исключение.
---
### Пишем свой контекстный менеджер “вручную”
Простой пример — измерение времени работы блока кода:
import time
class Timer:
def __enter__(self):
self.start = time.perf_counter()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.perf_counter()
self.elapsed = self.end - self.start
print(f"Elapsed: {self.elapsed:.4f} seconds")
with Timer() as t:
total = sum(range(1_000_000))
Плюсы: полный контроль, можно хранить состояние в атрибутах объекта. Минус: много шаблонного кода.
---
### contextlib.contextmanager: контекстный менеджер из функции
Модуль contextlib позволяет писать их короче, с помощью генераторов:
from contextlib import contextmanager
@contextmanager
def open_file(path, mode="r"):
f = open(path, mode)
try:
yield f # то, что вернётся в "as"
finally:
f.close() # выполнится всегда
with open_file("data.txt") as f:
data = f.read()
Всё, что до yield, — это логика __enter__, а всё после — __exit__.
---
### Практический пример: временная смена текущей директории
import os
from contextlib import contextmanager
@contextmanager
def change_dir(path):
old_dir = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(old_dir)
print(os.getcwd())
with change_dir("/tmp"):
print(os.getcwd())
print(os.getcwd())
Контекст гарантирует, что директория вернётся к исходной даже при ошибках внутри блока with.
---
### Когда стоит использовать контекстные менеджеры
- работа с файлами и сетевыми соединениями;
- блокировки потоков и транзакции в БД;
- временные настройки (логирование, окружение, директории);
- любые ресурсы, которые надо обязательно освободить.
Контекстный менеджер — это способ формально описать жизненный цикл ресурса: “взял → поработал → убрал за собой”, и contextlib делает это описание максимально коротким и наглядным. | 0 |
| 8 | Понимание работы контекстных менеджеров и создание своих с помощью contextlib | 0 |
| 9 | Создание простых HTTP-запросов вручную с модулем http.client
Большинство новичков начинают работу с сетью через библиотеку requests. Она удобная и «магическая». Но если хочется понять, что реально происходит под капотом, полезно познакомиться с модулем стандартной библиотеки http.client.
http.client работает на более низком уровне: вы сами открываете соединение, отправляете строку запроса, заголовки, читаете ответ. Немного «олдскул», зато отлично прокачивает понимание HTTP.
---
### Простой GET-запрос
Сделаем обычный GET-запрос к публичному API:
import http.client
import json
conn = http.client.HTTPSConnection("api.github.com")
headers = {
"User-Agent": "python-http.client-demo",
"Accept": "application/vnd.github.v3+json"
}
conn.request("GET", "/repos/python/cpython", headers=headers)
response = conn.getresponse()
print("Status:", response.status, response.reason)
data = response.read()
payload = json.loads(data)
print("Full name:", payload["full_name"])
print("Stars:", payload["stargazers_count"])
conn.close()
Что здесь важно:
- HTTPSConnection — шифрованное соединение (TLS).
- request(method, url, body=None, headers={}) — отправка запроса.
- getresponse() — возвращает объект ответа.
- status, reason, read() — статус-код, текстовое описание и тело ответа.
Без обязательного заголовка User-Agent GitHub может ответить ошибкой — это хороший пример, почему заголовки критичны.
---
### Отправка POST-запроса с данными
Теперь отправим POST с JSON-данными на тестовый сервис httpbin.org:
import http.client
import json
conn = http.client.HTTPSConnection("httpbin.org")
payload = {"name": "Alice", "lang": "Python"}
body = json.dumps(payload)
headers = {
"Content-Type": "application/json",
"Content-Length": str(len(body))
}
conn.request("POST", "/post", body=body, headers=headers)
response = conn.getresponse()
print("Status:", response.status)
response_data = response.read().decode("utf-8")
print("Response body:", response_data[:200], "...")
conn.close()
Здесь уже видно «ручную работу»:
- Сериализуем данные сами (json.dumps).
- Указываем Content-Type и Content-Length вручную.
- Сами кодируем/декодируем текст (decode("utf-8")).
---
### Зачем это нужно?
- Понимание того, как устроен HTTP «на проводе».
- Возможность тонко контролировать заголовки и поведение соединения.
- Умение работать только со стандартной библиотекой, без внешних зависимостей.
После таких упражнений любые высокоуровневые библиотеки кажутся гораздо понятнее: вы уже знаете, какую именно «рутину» они берут на себя. | 0 |
| 10 | Создание простых HTTP-запросов вручную с модулем http.client | 0 |
| 11 | Python для начинающих: как pathlib спасет вас от хаоса с путями
Если вы хоть раз писали что-то вроде:
file_path = "C:\\Users\\user\\projects\\data\\file.txt"
и ловили ошибки из‑за слэшей и кодировок, то модуль pathlib — ваш новый лучший друг. Он превращает работу с путями и файлами в аккуратные объектные операции, вместо бесконечной возни со строками.
---
### Базовая идея: Path вместо строк
Главный герой — класс Path:
from pathlib import Path
base_dir = Path.home() / "projects" / "demo"
print(base_dir)
Оператор / здесь не делит, а красиво склеивает части пути, независимо от ОС (Windows, Linux, macOS). Никаких os.path.join, никаких ручных слэшей.
---
### Проверка существования и типа
pathlib сразу умеет отвечать на важные вопросы:
from pathlib import Path
path = Path("data/example.txt")
print(path.exists()) # файл или папка есть?
print(path.is_file()) # это файл?
print(path.is_dir()) # это папка?
Можно безопасно проверять перед чтением или удалением.
---
### Чтение и запись файлов
Чтение и запись — это методы объекта пути:
from pathlib import Path
file_path = Path("data/notes.txt")
# запись текста
file_path.write_text("Hello, pathlib!", encoding="utf-8")
# чтение текста
content = file_path.read_text(encoding="utf-8")
print(content)
Не нужно вручную открывать и закрывать файлы — Path делает это за вас.
---
### Создание папок и обход директорий
Создать дерево каталогов и пройтись по файлам — одна строка:
from pathlib import Path
base = Path("logs/app")
# создаем все недостающие каталоги
base.mkdir(parents=True, exist_ok=True)
# ищем все .log файлы в подпапках
for log_file in base.rglob("*.log"):
print(log_file.name, log_file.stat().st_size, "bytes")
Метод rglob рекурсивно ищет файлы по шаблону, stat() дает информацию о файле.
---
### Работа с именами, расширениями и родителями
Разбирать путь по частям стало легко:
from pathlib import Path
path = Path("data/archive/report_2024.csv")
print(path.name) # report_2024.csv
print(path.stem) # report_2024
print(path.suffix) # .csv
print(path.parent) # data/archive
new_path = path.with_suffix(".xlsx")
print(new_path) # data/archive/report_2024.xlsx
---
### Почему стоит перейти на pathlib уже сейчас
- Кроссплатформенно: один и тот же код под Windows и Linux.
- Читаемо: Path‑объекты ведут себя как реальные объекты, а не как странные строки.
- Богатый функционал: от обхода директорий до смены расширений.
Если вы еще работаете с путями как со строками — попробуйте переписать небольшой скрипт на pathlib. Скорее всего, назад уже не захочется. | 0 |
| 12 | Использование pathlib для работы с путями и файлами | 0 |
| 13 | Python для начинающих: configparser — приручаем конфиги как профи
Жёстко прописывать настройки прямо в коде — плохая идея. Захочется сменить пароль к базе или лог‑уровень — и вы уже лазите по файлам Python, рискуя всё сломать. Гораздо удобнее хранить настройки в конфигурационных файлах. Для этого в стандартной библиотеке есть модуль configparser.
---
### Как выглядит конфиг
Создадим файл settings.ini:
[database]
host = localhost
port = 5432
user = admin
password = secret
[logging]
level = DEBUG
file = app.log
Структура проста: секции в квадратных скобках и пары ключ = значение.
---
### Чтение конфигурации
from configparser import ConfigParser
config = ConfigParser()
config.read("settings.ini")
db_host = config["database"]["host"]
db_port = config.getint("database", "port")
log_level = config.get("logging", "level", fallback="INFO")
print(db_host, db_port, log_level)
Ключевые моменты:
- config["section"]["option"] — базовый доступ.
- getint, getfloat, getboolean — сразу приводят к нужному типу.
- fallback спасает, если ключа нет.
---
### Изменение и сохранение конфига
from configparser import ConfigParser
config = ConfigParser()
config.read("settings.ini")
config["database"]["host"] = "db.mycompany.com"
if "feature_flags" not in config:
config["feature_flags"] = {}
config["feature_flags"]["new_ui"] = "true"
with open("settings.ini", "w") as configfile:
config.write(configfile)
Так можно не только читать, но и аккуратно обновлять настройки.
---
### Конфиг по умолчанию
Иногда нужно задать значения «на всякий случай»:
from configparser import ConfigParser
config = ConfigParser(
defaults={
"level": "INFO",
"file": "app.log"
}
)
config.read("settings.ini")
log_level = config["logging"]["level"] # если нет в секции, возьмёт из defaults
log_file = config["logging"]["file"]
---
### Когда это полезно
- разные настройки для dev / prod без изменения кода;
- хранение секретов вне репозитория (через отдельный local_settings.ini);
- быстрое переключение фич через флаги.
configparser — простой, но мощный способ отделить код от настроек. Один раз настроили структуру .ini — и дальше ваш код становится гораздо чище и гибче. | 0 |
| 14 | Подключение и использование конфигурационных файлов с configparser | 0 |
| 15 | Python для начинающих: как enum делает код понятнее
Когда в коде появляются «магические числа» и странные строки, читаемость падает. Встречали что‑то вроде:
if status == 3:
send_email()
Через неделю уже непонятно, что такое 3. Ошибка не в логике — ошибка в обозначениях. Здесь на сцену выходит модуль enum.
---
## Что такое Enum?
Enum (перечисление) — это способ задать набор именованных констант. Вместо чисел и строк, разбросанных по коду, вы используете говорящие имена.
from enum import Enum
class OrderStatus(Enum):
NEW = 1
PAID = 2
SHIPPED = 3
CANCELED = 4
Теперь вместо 3 у вас есть OrderStatus.SHIPPED. Код сразу объясняет сам себя.
---
## Пример: читаемый if
До:
def handle_order(status):
if status == 1:
print("Create invoice")
elif status == 2:
print("Prepare shipment")
elif status == 3:
print("Send tracking code")
После:
from enum import Enum
class OrderStatus(Enum):
NEW = 1
PAID = 2
SHIPPED = 3
def handle_order(status: OrderStatus):
if status is OrderStatus.NEW:
print("Create invoice")
elif status is OrderStatus.PAID:
print("Prepare shipment")
elif status is OrderStatus.SHIPPED:
print("Send tracking code")
Что улучшилось:
- код сам документирует возможные статусы;
- меньше шансов перепутать значения;
- IDE подсказывает варианты (OrderStatus. → список).
---
## Enum вместо строк
Частая ловушка — сравнение со строками:
if role == "admin":
...
Опечатка — и проверка ломается. С Enum:
from enum import Enum, auto
class UserRole(Enum):
ADMIN = auto()
EDITOR = auto()
VIEWER = auto()
def can_delete(user_role: UserRole) -> bool:
return user_role is UserRole.ADMIN
auto() сам проставит уникальные значения — нас интересуют не числа, а имена.
---
## Небольшой бонус: словари с Enum
Enum удобно использовать как ключи:
from enum import Enum, auto
class LogLevel(Enum):
DEBUG = auto()
INFO = auto()
ERROR = auto()
LOG_PREFIXES = {
LogLevel.DEBUG: "[DEBUG]",
LogLevel.INFO: "[INFO]",
LogLevel.ERROR: "[ERROR]",
}
def log(level: LogLevel, message: str) -> None:
prefix = LOG_PREFIXES[level]
print(prefix, message)
Здесь невозможно случайно обратиться к "DBG" вместо "DEBUG" — только валидные значения перечисления.
---
Enum — это маленькое улучшение, которое сильно поднимает читаемость и надежность кода. Как только в вашем проекте появляется набор фиксированных состояний, ролей, типов — это сигнал: пора завести перечисление. | 0 |
| 16 | Как применять enum для улучшения читаемости кода | 0 |
| 17 | Создание генераторов: экономим память при обработке больших данных
Представьте, что вам нужно обработать файл на 10 ГБ, посчитать суммы, отфильтровать строки, что‑то преобразовать. Если пытаться «затащить» всё в память списками — привет, MemoryError. Здесь на сцену выходят генераторы.
Генератор — это «ленивый» источник данных: он отдаёт элементы по одному, по запросу, не храня весь результат сразу. Именно поэтому генераторы так хорошо подходят для больших данных и потоковой обработки.
### Генераторные выражения
Список:
nums = [i * 2 for i in range(10_000_000)]
держит в памяти все 10 млн элементов.
Генератор:
nums_gen = (i * 2 for i in range(10_000_000))
хранит только текущее состояние итерации. Память почти не растёт, пока вы не начинаете обходить nums_gen:
total = 0
for value in nums_gen:
total += value
### Собственные генераторные функции
Ключевое слово yield превращает функцию в генератор:
def read_large_file(path):
with open(path, 'r', encoding='utf-8') as f:
for line in f:
yield line.strip()
Здесь не создаётся список строк файла — каждая строка обрабатывается по мере чтения:
def iter_error_lines(path):
for line in read_large_file(path):
if 'ERROR' in line:
yield line
for err_line in iter_error_lines('app.log'):
print(err_line)
Файл может быть гигантским — программа использует почти столько же памяти, как и при чтении маленького файла.
### Конвейер из генераторов
Самое интересное начинается, когда вы соединяете генераторы в цепочку — получается «конвейер»:
def iter_numbers(path):
for line in read_large_file(path):
if line and line[0].isdigit():
yield int(line)
def filter_even(seq):
for n in seq:
if n % 2 == 0:
yield n
def sum_limited(seq, limit):
total = 0
for n in seq:
total += n
if total > limit:
break
return total
numbers = iter_numbers('numbers.txt')
even_numbers = filter_even(numbers)
result = sum_limited(even_numbers, limit=1_000_000)
print(result)
Каждый шаг обрабатывает элементы по одному: прочитали строку → превратили в число → отфильтровали → учли в сумме. Никаких огромных временных списков.
### Когда использовать генераторы
- Обработка больших файлов и потоков данных.
- Длинные вычисления, результат которых нужен по частям.
- Организация удобных «ленивых» API (итераторы вместо списков).
Генераторы — это простой способ сделать код и аккуратнее, и экономичнее по памяти, не усложняя архитектуру. Если вы уже пишете списковые включения, вы почти готовы использовать генераторы — достаточно заменить [] на (). | 0 |
| 18 | Создание генераторов: экономим память при обработке больших данных | 0 |
| 19 | Работа с collections: полезные структуры данных и где их использовать
Стандартные списки и словари — отличная вещь, но модуль collections превращает их в инструменты «профессионального уровня». Разберём ключевые структуры, которые реально упрощают код.
---
### Counter: считаем всё подряд
Counter — словарь для подсчёта объектов.
from collections import Counter
text = "banana bandana"
counter = Counter(text)
print(counter) # сколько раз встречается каждый символ
print(counter.most_common(2)) # два самых частых
Где полезно: подсчёт частоты слов в тексте, статистика действий пользователей, анализ логов.
---
### defaultdict: словарь, который не ругается на новые ключи
Обычный словарь бросит KeyError, если ключа нет. defaultdict автоматически создаёт значение по умолчанию.
from collections import defaultdict
groups = defaultdict(list)
data = [("cat", 1), ("dog", 2), ("cat", 3)]
for animal, value in data:
groups[animal].append(value)
print(groups) # {'cat': [1, 3], 'dog': [2]}
Где полезно: группировка данных, инвертирование словарей, построение графов (списки соседей).
---
### namedtuple: читаемые «кортежи с именами»
Обычный кортеж непонятен: user[0], user[1]… namedtuple даёт имена полям.
from collections import namedtuple
User = namedtuple("User", ["name", "age"])
user = User(name="Alice", age=30)
print(user.name)
print(user.age)
Где полезно: лёгкие «объекты без классов» — координаты, настройки, параметры функций. Иммутабельность помогает избежать случайных изменений.
---
### deque: очередь и стек без тормозов
Список плохо работает с pop(0) — это O(n). deque оптимизирован для добавления/удаления с обоих концов.
from collections import deque
queue = deque()
queue.append("task1")
queue.append("task2")
queue.appendleft("urgent")
print(queue.popleft()) # 'urgent'
print(queue.pop()) # 'task2'
Где полезно: очереди задач, реализовать стек/очередь, «скользящее окно» последних N элементов.
---
### OrderedDict: порядок тоже важен
С Python 3.7 обычный dict уже запоминает порядок вставки, но OrderedDict всё ещё полезен там, где нужны дополнительные операции (например, move_to_end). В современных проектах используют реже, но стоит знать о его существовании.
---
Модуль collections — это набор готовых решений для типичных задач работы с данными. Зная эти структуры, вы часто пишете меньше кода, делаете его быстрее и понятнее — и меньше изобретаете велосипеды. | 0 |
| 20 | Работа с collections: полезные структуры данных и где их использовать | 0 |
متاح الآن! بحث تيليغرام 2025 — أهم رؤى العام 
