🧠 List vs Set: Где искать быстрее?
Представьте, у вас есть массив из 1 миллиона чисел, и нужно проверить, есть ли в нем число 999999.
Что использовать: список (
Сравнение сложности:
▪️ List (in operator): Сложность . Python перебирает элементы по одному, пока не найдет нужное. Если список огромный, это долго.
▪️ Set (in operator): Сложность (в среднем). Множества реализованы как хеш-таблицы. Python вычисляет хеш числа и сразу "прыгает" в нужную ячейку памяти.
Тест скорости:
🚀 Итог: Если вам нужно часто проверять наличие элемента в большой коллекции - всегда конвертируйте её в set.
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Представьте, у вас есть массив из 1 миллиона чисел, и нужно проверить, есть ли в нем число 999999.
Что использовать: список (
list) или множество (set)?Сравнение сложности:
▪️ List (in operator): Сложность . Python перебирает элементы по одному, пока не найдет нужное. Если список огромный, это долго.
▪️ Set (in operator): Сложность (в среднем). Множества реализованы как хеш-таблицы. Python вычисляет хеш числа и сразу "прыгает" в нужную ячейку памяти.
Тест скорости:
import time
data_list = list(range(10_000_000))
data_set = set(data_list)
# Поиск в списке
start = time.time()
print(9999999 in data_list)
print(f"List time: {time.time() - start:.5f} sec")
# Поиск в множестве
start = time.time()
print(9999999 in data_set)
print(f"Set time: {time.time() - start:.5f} sec")
🚀 Итог: Если вам нужно часто проверять наличие элемента в большой коллекции - всегда конвертируйте её в set.
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
👍4❤3
🕵️♂️ Дебаг без боли: секрет f-строк
Признавайтесь, вы тоже часто пишете такие принты, чтобы проверить значение переменной?
Это работает, но писать каждый раз название переменной в кавычках — долго и лениво. В Python есть супер-фишка для f-строк, о которой многие забывают. Просто добавьте знак равно
Как это выглядит:
Вывод:
🔥 Почему это круто: Python сам подставляет имя переменной и её значение. Экономит кучу времени при поиске багов!
Знали про этот трюк? Ставьте ❤️, если уже пользуетесь!
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Признавайтесь, вы тоже часто пишете такие принты, чтобы проверить значение переменной?
name = "Alex"
age = 25
print("name =", name)
print("age =", age)
Это работает, но писать каждый раз название переменной в кавычках — долго и лениво. В Python есть супер-фишка для f-строк, о которой многие забывают. Просто добавьте знак равно
= после имени переменной внутри фигурных скобок!Как это выглядит:
name = "Alex"
age = 25
print(f"{name=}")
print(f"{age=}")
Вывод:
name='Alex'
age=25
🔥 Почему это круто: Python сам подставляет имя переменной и её значение. Экономит кучу времени при поиске багов!
Знали про этот трюк? Ставьте ❤️, если уже пользуетесь!
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
👍11
🧩 Задача: Проверка на анаграмму
Анаграммы, это слова, состоящие из одних и тех же букв, но в разном порядке. Например:
Как проверить, являются ли две строки анаграммами, максимально эффективно?
Вариант 1 (В лоб): Сортировка
Мы можем отсортировать обе строки и сравнить их.
Это работает, но сложность сортировки - O(N log N) . Можно ли быстрее? 🤔
Вариант 2 (Оптимальный): Подсчет символов
Используем словарь (или
💡 Совет: На собеседованиях всегда предлагайте сначала решение с сортировкой (оно проще), а потом удивляйте интервьюера знанием сложности алгоритмов и вариантом с хеш-таблицей (Counter)!
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Анаграммы, это слова, состоящие из одних и тех же букв, но в разном порядке. Например:
ток и кот.Как проверить, являются ли две строки анаграммами, максимально эффективно?
Вариант 1 (В лоб): Сортировка
Мы можем отсортировать обе строки и сравнить их.
def is_anagram(s1, s2):
return sorted(s1) == sorted(s2)
Это работает, но сложность сортировки - O(N log N) . Можно ли быстрее? 🤔
Вариант 2 (Оптимальный): Подсчет символов
Используем словарь (или
Counter), чтобы посчитать, сколько раз встречается каждая буква. Сложность такого решения - O(N) , то есть линейная (самая быстрая).
from collections import Counter
def is_anagram_fast(s1, s2):
return Counter(s1) == Counter(s2)
print(is_anagram_fast("listen", "silent")) # True
💡 Совет: На собеседованиях всегда предлагайте сначала решение с сортировкой (оно проще), а потом удивляйте интервьюера знанием сложности алгоритмов и вариантом с хеш-таблицей (Counter)!
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
❤6👍3
☠️ Самая частая ошибка новичков в Python
Посмотрите на этот код. Как думаете, что пошло не так?
Ожидание:
Реальность:
Почему так произошло?
В Python аргументы по умолчанию создаются один раз при запуске программы (когда интерпретатор читает
✅ Как писать правильно:
Используйте None как маркер пустого значения.
Сохраняй пост, чтобы не наступать на эти грабли! 💾
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Посмотрите на этот код. Как думаете, что пошло не так?
def add_item(item, basket=[]):
basket.append(item)
return basket
print(add_item("Яблоко"))
print(add_item("Банан"))
Ожидание:
['Яблоко']
['Банан']Реальность:
['Яблоко']
['Яблоко', 'Банан'] 😱Почему так произошло?
В Python аргументы по умолчанию создаются один раз при запуске программы (когда интерпретатор читает
def), а не при каждом вызове функции. Поэтому список basket - это один и тот же объект в памяти для всех вызовов!✅ Как писать правильно:
Используйте None как маркер пустого значения.
def add_item(item, basket=None):
if basket is None:
basket = []
basket.append(item)
return basket
Сохраняй пост, чтобы не наступать на эти грабли! 💾
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
👍4🔥3🥱1
🌐 Твой первый API запрос на Python
Если нужно получить данные с сайта (курс валют, погоду или список постов), библиотека
Допустим, мы хотим получить шутку с бесплатного API.
Как это сделать в 3 строчки:
📌 Разбор:
🟢
🟢
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Если нужно получить данные с сайта (курс валют, погоду или список постов), библиотека
requests - твой лучший друг. Она делает общение с интернетом невероятно простым.Допустим, мы хотим получить шутку с бесплатного API.
Как это сделать в 3 строчки:
import requests
# 1. Делаем GET-запрос по адресу
url = "https://official-joke-api.appspot.com/random_joke"
response = requests.get(url)
# 2. Проверяем, что всё ок (код 200)
if response.status_code == 200:
# 3. Превращаем ответ из JSON в словарь Python
data = response.json()
print(f"Шутка: {data['setup']} - {data['punchline']}")
else:
print("Ошибка соединения 😢")
📌 Разбор:
.status_code - показывает, как прошел запрос (200 = ОК, 404 = Не найдено, 500 = Ошибка сервера)..json() - это магия, которая превращает строку текста от сервера сразу в понятный Python-словарь.📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🛠 Передаем параметры красиво
Частая ошибка новичков, склеивать параметры запроса вручную прямо в URL.
❌ Как НЕ надо делать:
✅ Как НАДО делать:
Используйте аргумент
Это делает код чище, безопаснее и профессиональнее. 😎
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Частая ошибка новичков, склеивать параметры запроса вручную прямо в URL.
❌ Как НЕ надо делать:
user_id = 12
# Плохо: сложно читать, легко ошибиться, проблемы со спецсимволами
url = "https://jsonplaceholder.typicode.com/posts?userId=" + str(user_id)
r = requests.get(url)
✅ Как НАДО делать:
Используйте аргумент
params. Библиотека сама всё склеит и, что важно, правильно закодирует символы (например, заменит пробелы на %20).
import requests
url = "https://jsonplaceholder.typicode.com/posts"
# Параметры кладем в словарь
my_params = {
"userId": 1,
"_limit": 5
}
# Передаем словарь в функцию
response = requests.get(url, params=my_params)
print(response.url)
# Вывод: .../posts?userId=1&_limit=5
Это делает код чище, безопаснее и профессиональнее. 😎
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
❤5👍1
🚀 Ускоряем массовые запросы: Sessions
Представьте, что вам нужно скачать 100 страниц сайта. Если делать это через обычный
1. Открытие соединения (TCP Handshake).
2. Настройка шифрования (SSL/TLS).
3. Отправка данных.
4. Закрытие соединения.
Это очень долго! 🐢
Решение: Session
Сессия позволяет переиспользовать одно и то же соединение для множества запросов. Это дает огромный прирост скорости.
Пример:
💡Сессия также запоминает куки (cookies). Если вы авторизовались на сайте в первом запросе, сессия "запомнит" это для следующих.
Используйте сессии, если делаете больше двух запросов к одному сайту!
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Представьте, что вам нужно скачать 100 страниц сайта. Если делать это через обычный
requests.get(), каждый раз будет происходить следующее:1. Открытие соединения (TCP Handshake).
2. Настройка шифрования (SSL/TLS).
3. Отправка данных.
4. Закрытие соединения.
Это очень долго! 🐢
Решение: Session
Сессия позволяет переиспользовать одно и то же соединение для множества запросов. Это дает огромный прирост скорости.
Пример:
import requests
# Создаем сессию
with requests.Session() as s:
# Можно сразу настроить заголовки для всех запросов
s.headers.update({'User-Agent': 'my-app/0.0.1'})
for i in range(5):
# Используем s.get вместо requests.get
r = s.get(f"https://httpbin.org/get?page={i}")
print(f"Запрос {i} выполнен!")
💡Сессия также запоминает куки (cookies). Если вы авторизовались на сайте в первом запросе, сессия "запомнит" это для следующих.
Используйте сессии, если делаете больше двух запросов к одному сайту!
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
👍4
🛑 Твой код завис навсегда? Исправляем!
Знаете ли вы, что по умолчанию библиотека
Если сервер, к которому вы обращаетесь, "упал" или просто завис, ваш Python-скрипт тоже встанет и будет висеть вечно, пока вы не убьете процесс вручную. В продакшене (да и в пет-проектах) это недопустимо! 🚫
✅ Решение: Всегда используйте
Параметр
Пример безопасного кода:
💡 Совет: Хорошей практикой считается ставить таймаут в диапазоне 3–10 секунд для обычных запросов.
Проверьте свои старые проекты, есть ли там
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Знаете ли вы, что по умолчанию библиотека
requests ждет ответа от сервера бесконечно?Если сервер, к которому вы обращаетесь, "упал" или просто завис, ваш Python-скрипт тоже встанет и будет висеть вечно, пока вы не убьете процесс вручную. В продакшене (да и в пет-проектах) это недопустимо! 🚫
✅ Решение: Всегда используйте
timeoutПараметр
timeout указывает, сколько секунд ждать ответа, прежде чем выбросить ошибку и продолжить работу.Пример безопасного кода:
import requests
from requests.exceptions import Timeout, ConnectionError
url = "https://httpbin.org/delay/5" # Сервер ответит через 5 сек
try:
# Ставим таймаут 2 секунды.
# Если сервер не ответит за 2 сек — скрипт не зависнет!
response = requests.get(url, timeout=2)
response.raise_for_status() # Проверка на ошибки 4xx/5xx
print("Успех:", response.json())
except Timeout:
print("⏰ Ошибка: Сервер отвечает слишком долго!")
except ConnectionError:
print("🔌 Ошибка: Нет интернета или сайт недоступен.")
except Exception as e:
print(f"Что-то пошло не так: {e}")
💡 Совет: Хорошей практикой считается ставить таймаут в диапазоне 3–10 секунд для обычных запросов.
Проверьте свои старые проекты, есть ли там
timeout? Если нет, самое время добавить! 👨💻📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
👍6
🚀 Синхронность vs Асинхронность: Ускоряем код в 10 раз
Представьте, что вы стоите в очереди в Макдональдс.
🐢 Синхронный подход (как
Кассир принимает ваш заказ, уходит на кухню, ждет, пока пожарится картошка, наливает колу, отдает заказ вам и только потом обращается к следующему человеку в очереди. Медленно? Ужасно медленно!
⚡️ Асинхронный подход (как
Кассир принимает заказ, кричит на кухню "Свободная касса!" и сразу берет заказ у следующего, пока ваш готовится. Работа идет параллельно.
В Python для этого используется библиотека
Сравним на практике:
Допустим, нам нужно скачать 10 страниц.
Результат:
Если
🛠 Установка:
⚠️ Важно: Не используйте это для атак на сайты (DDoS). Сервер может забанить вас за слишком большое количество запросов в секунду.
Сохраняй, пригодится для парсинга больших объемов данных! 🔥
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Представьте, что вы стоите в очереди в Макдональдс.
🐢 Синхронный подход (как
requests):Кассир принимает ваш заказ, уходит на кухню, ждет, пока пожарится картошка, наливает колу, отдает заказ вам и только потом обращается к следующему человеку в очереди. Медленно? Ужасно медленно!
⚡️ Асинхронный подход (как
aiohttp):Кассир принимает заказ, кричит на кухню "Свободная касса!" и сразу берет заказ у следующего, пока ваш готовится. Работа идет параллельно.
В Python для этого используется библиотека
aiohttp и ключевые слова async / await.Сравним на практике:
Допустим, нам нужно скачать 10 страниц.
import asyncio
import aiohttp
import time
# Функция для одного запроса
async def fetch_page(session, url):
async with session.get(url) as response:
return response.status
async def main():
urls = ["https://google.com" for _ in range(10)] # 10 запросов
async with aiohttp.ClientSession() as session:
tasks = []
for url in urls:
# Создаем задачи, но еще не запускаем их ожидание
tasks.append(fetch_page(session, url))
# Запускаем все задачи одновременно!
await asyncio.gather(*tasks)
start = time.time()
# Запуск асинхронного цикла
asyncio.run(main())
print(f"Время выполнения: {time.time() - start:.2f} сек")
Результат:
Если
requests будет делать это ~10 секунд (по 1 сек на запрос), то aiohttp справится за ~1.2 секунды. Он просто отправит все 10 запросов разом и будет ждать ответы.🛠 Установка:
pip install aiohttp⚠️ Важно: Не используйте это для атак на сайты (DDoS). Сервер может забанить вас за слишком большое количество запросов в секунду.
Сохраняй, пригодится для парсинга больших объемов данных! 🔥
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
👍3😱1🥴1
🤖 Твой первый Telegram-бот на aiogram
Мы уже выяснили, что асинхронность это круто. А где она используется чаще всего? Конечно, в Telegram-ботах!
Сегодня напишем "Эхо-бота" - это как "Hello World" в мире ботов. Он будет просто повторять всё, что мы ему напишем.
🛠 Подготовка:
1. Идем к «отцу всех ботов» - @BotFather.
2. Пишем
3. Получаем API TOKEN (длинная строка символов).
4. Устанавливаем библиотеку:
💻 Код (всего 20 строк):
🧩 Разбор магии:
🟢
🟢
🟢
Скопируй, вставь токен и запусти. Поздравляю, ты только что создал своего бота! 🎉
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Мы уже выяснили, что асинхронность это круто. А где она используется чаще всего? Конечно, в Telegram-ботах!
Сегодня напишем "Эхо-бота" - это как "Hello World" в мире ботов. Он будет просто повторять всё, что мы ему напишем.
🛠 Подготовка:
1. Идем к «отцу всех ботов» - @BotFather.
2. Пишем
/newbot, даем имя и юзернейм.3. Получаем API TOKEN (длинная строка символов).
4. Устанавливаем библиотеку:
pip install aiogram💻 Код (всего 20 строк):
import asyncio
import logging
from aiogram import Bot, Dispatcher, types
from aiogram.filters import CommandStart
# Вставь сюда токен от BotFather
TOKEN = "ВАШ_ТОКЕН_ЗДЕСЬ"
# Включаем логирование, чтобы видеть ошибки в консоли
logging.basicConfig(level=logging.INFO)
# Создаем объекты бота и диспетчера
bot = Bot(token=TOKEN)
dp = Dispatcher()
# 1. Обработчик команды /start
@dp.message(CommandStart())
async def cmd_start(message: types.Message):
await message.answer("Привет! Я твой первый бот на aiogram 🚀")
# 2. Обработчик любого текста (Эхо)
@dp.message()
async def echo_handler(message: types.Message):
# Метод .answer() отправляет ответ в тот же чат
await message.answer(f"Ты написал: {message.text}")
# Запуск процесса опроса (polling)
async def main():
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
🧩 Разбор магии:
Dispatcher (dp) - это мозг бота. Он получает сообщения от Telegram и решает, какой функции их передать.@dp.message(...) - это декораторы. Они "фильтруют" сообщения.await message.answer(...) - асинхронная отправка сообщения. Пока бот отправляет ответ тебе, он может параллельно обрабатывать сообщения от других пользователей!Скопируй, вставь токен и запусти. Поздравляю, ты только что создал своего бота! 🎉
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1🤔1
🎛 Делаем бота удобным: Кнопки и Меню
Никто не любит вводить команды вручную (
1. Reply-кнопки: Находятся под полем ввода. Идеальны для главного меню.
2. Inline-кнопки: Прикреплены к конкретному сообщению. Идеальны для ссылок, лайков или навигации.
Давайте добавим оба вида в нашего бота!
🛠 Код:
💡 В чем сила Builders?
Метод
Сохраняй, чтобы не гуглить синтаксис каждый раз! 💾
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Никто не любит вводить команды вручную (
/settings, /help). Пользователи любят тыкать пальцем! В Telegram есть два вида кнопок:1. Reply-кнопки: Находятся под полем ввода. Идеальны для главного меню.
2. Inline-кнопки: Прикреплены к конкретному сообщению. Идеальны для ссылок, лайков или навигации.
Давайте добавим оба вида в нашего бота!
🛠 Код:
from aiogram.types import KeyboardButton, InlineKeyboardButton
from aiogram.utils.keyboard import ReplyKeyboardBuilder, InlineKeyboardBuilder
# --- 1. Создаем Reply-клавиатуру (Главное меню) ---
def get_main_menu():
# Инициализируем билдер
builder = ReplyKeyboardBuilder()
# Добавляем кнопки
builder.add(KeyboardButton(text="🔥 Профиль"))
builder.add(KeyboardButton(text="⚙️ Настройки"))
builder.add(KeyboardButton(text="📈 Статистика"))
# Настраиваем сетку: 2 кнопки в первом ряду, 1 во втором
builder.adjust(2, 1)
# resize_keyboard=True делает кнопки компактными
return builder.as_markup(resize_keyboard=True)
# --- 2. Создаем Inline-клавиатуру (Ссылка) ---
def get_url_keyboard():
builder = InlineKeyboardBuilder()
builder.row(InlineKeyboardButton(
text="↗️ Подписаться на канал",
url="https://news.1rj.ru/str/pythonofff"
))
return builder.as_markup()
# --- Используем в хэндлере ---
@dp.message(Command("start"))
async def cmd_start(message: types.Message):
await message.answer(
"Привет! Вот твое меню 👇",
reply_markup=get_main_menu()
)
await message.answer(
"А это инлайн-кнопка со ссылкой:",
reply_markup=get_url_keyboard()
)
💡 В чем сила Builders?
Метод
.adjust(2, 1) позволяет одной строчкой настроить "сетку" кнопок. Раньше для этого приходилось писать сложные циклы списков!Сохраняй, чтобы не гуглить синтаксис каждый раз! 💾
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
👍3
✨ Магия Python: Как работают декораторы?
Вы постоянно видите их в коде:
В Python функции - это объекты. Их можно передавать в другие функции, как обычные переменные.
Декоратор - это просто функция, которая принимает другую функцию, "обертывает" её в дополнительный код и возвращает обратно.
Представьте, что у вас есть подарок (функция). Декоратор - это упаковочная бумага. Подарок внутри тот же, но теперь он выглядит и ведет себя немного иначе.
Пример: Декоратор-логгер
Допустим, мы хотим автоматически писать в консоль, когда функция запустилась и когда завершилась.
Результат в консоли:
🤯 Что происходит под капотом?
Синтаксис с
А как это работает в ботах (@dp.message)?
В библиотеках типа
Когда вы пишете
Итог: Декораторы нужны, чтобы добавить логику вокруг функции (проверка прав доступа, замер скорости, логирование), не меняя её код внутри.
Ставь ❤️, если магия рассеялась и стало понятнее!
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Вы постоянно видите их в коде:
@bot.message_handler, @app.route, @staticmethod. Но что на самом деле делает этот символ @?В Python функции - это объекты. Их можно передавать в другие функции, как обычные переменные.
Декоратор - это просто функция, которая принимает другую функцию, "обертывает" её в дополнительный код и возвращает обратно.
Представьте, что у вас есть подарок (функция). Декоратор - это упаковочная бумага. Подарок внутри тот же, но теперь он выглядит и ведет себя немного иначе.
Пример: Декоратор-логгер
Допустим, мы хотим автоматически писать в консоль, когда функция запустилась и когда завершилась.
def my_logger(func):
def wrapper():
print("📢 Запускаю функцию...")
func() # Вызываем оригинальную функцию
print("✅ Функция отработала!")
return wrapper
# Применяем декоратор
@my_logger
def say_hello():
print("Привет, мир!")
# Вызываем
say_hello()
Результат в консоли:
📢 Запускаю функцию...
Привет, мир!
✅ Функция отработала!
🤯 Что происходит под капотом?
Синтаксис с
@ - это просто "сахар" (упрощение). На самом деле Python делает вот это:
# Это:
@my_logger
def say_hello(): ...
# Равносильно этому:
def say_hello(): ...
say_hello = my_logger(say_hello)
А как это работает в ботах (@dp.message)?
В библиотеках типа
aiogram декораторы часто используются для регистрации.Когда вы пишете
@dp.message(), декоратор не меняет код вашей функции, а сообщает Диспетчеру: "Эй, запомни эту функцию! Если придет сообщение, нужно запустить именно её".Итог: Декораторы нужны, чтобы добавить логику вокруг функции (проверка прав доступа, замер скорости, логирование), не меняя её код внутри.
Ставь ❤️, если магия рассеялась и стало понятнее!
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
❤6👍2
⚡ Lambda: Функции-однострочники
В Python часто бывают ситуации, когда вам нужна маленькая функция всего один раз. Например, чтобы отсортировать список по хитрому правилу.
Писать для этого полноценный
Синтаксис прост:
Сравните:
🔥 Где это реально нужно?
Чаще всего - внутри функций
Пример из жизни:
У нас есть список студентов и их баллов. Нам нужно отсортировать их не по имени, а по баллам.
Внутри
🛑 Когда НЕ надо использовать Lambda:
Не присваивайте лямбды переменным, если планируете использовать их много раз.
Лямбды созданы, чтобы быть "одноразовыми"!
Используете лямбды или предпочитаете старый добрый
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
В Python часто бывают ситуации, когда вам нужна маленькая функция всего один раз. Например, чтобы отсортировать список по хитрому правилу.
Писать для этого полноценный
def, придумывать имя и занимать 3 строки кода - лень и некрасиво. Тут на сцену выходят Lambda-функции (они же анонимные функции).Синтаксис прост:
lambda аргументы: выражениеСравните:
# Классический способ
def square(x):
return x ** 2
# Lambda-стиль
sq = lambda x: x ** 2
🔥 Где это реально нужно?
Чаще всего - внутри функций
sorted(), min(), max(), map() или filter().Пример из жизни:
У нас есть список студентов и их баллов. Нам нужно отсортировать их не по имени, а по баллам.
students = [
("Антон", 50),
("Вика", 90),
("Борис", 75)
]
# Сортируем по 2-му элементу кортежа (x[1])
sorted_students = sorted(students, key=lambda x: x[1])
print(sorted_students)
# [('Антон', 50), ('Борис', 75), ('Вика', 90)]
Внутри
key= мы на лету создали функцию, которая принимает студента x и возвращает его балл x[1]. sorted использует это значение для сортировки.🛑 Когда НЕ надо использовать Lambda:
Не присваивайте лямбды переменным, если планируете использовать их много раз.
# ❌ Плохо (нарушает PEP 8):
f = lambda x: x * 2
# ✅ Хорошо:
def f(x):
return x * 2
Лямбды созданы, чтобы быть "одноразовыми"!
Используете лямбды или предпочитаете старый добрый
def? 👇📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
👍3❤1
⚡ Магия одной строки: List Comprehension
Вы всё еще пишете циклы для заполнения списков вот так?
Это работает, но это "старая школа". В Python есть способ сделать это элегантнее, быстрее и понятнее - Списковые включения.
Как это выглядит:
Тот же самый код выше превращается в:
🚀 Почему это круто?
1. Лаконичность: Меньше кода меньше багов.
2. Скорость: Это работает быстрее обычного цикла
Уровень PRO: Добавляем условия
Внутри можно использовать
Задача: Оставить только четные числа и умножить их на 10.
💡 Совет: Не увлекайтесь! Если ваше выражение не влезает в одну строку или становится слишком сложным (например, вложенные циклы), лучше вернитесь к старому доброму
Часто используете эту конструкцию? Ставьте 🔥!
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Вы всё еще пишете циклы для заполнения списков вот так?
squares = []
for x in range(10):
squares.append(x ** 2)
Это работает, но это "старая школа". В Python есть способ сделать это элегантнее, быстрее и понятнее - Списковые включения.
Как это выглядит:
[выражение for элемент in список]Тот же самый код выше превращается в:
squares = [x ** 2 for x in range(10)]
🚀 Почему это круто?
1. Лаконичность: Меньше кода меньше багов.
2. Скорость: Это работает быстрее обычного цикла
for, потому что метод .append() не вызывается на каждой итерации (оптимизация на уровне C).Уровень PRO: Добавляем условия
Внутри можно использовать
if, чтобы фильтровать данные на лету.Задача: Оставить только четные числа и умножить их на 10.
numbers = [1, 2, 3, 4, 5, 6]
# Читается как английское предложение:
# "x умножить на 10 для каждого x в numbers, если x четный"
result = [x * 10 for x in numbers if x % 2 == 0]
print(result)
# [20, 40, 60]
💡 Совет: Не увлекайтесь! Если ваше выражение не влезает в одну строку или становится слишком сложным (например, вложенные циклы), лучше вернитесь к старому доброму
for. Читаемость важнее понтов!Часто используете эту конструкцию? Ставьте 🔥!
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
👍6🔥2
💾 Бесконечность не предел: Магия генераторов (yield)
В прошлом посте мы восхищались списковыми включениями
Представьте, что вам нужно обработать файл весом 10 ГБ. Если вы попытаетесь загрузить его в список
Тут на помощь приходят Генераторы.
В чем отличие?
🟢 📦 Список (
🟢 ⚙️ Генератор: Не хранит данные. Он генерирует следующее значение только тогда, когда вы его попросите. Как рассказчик, который придумывает историю на ходу.
Как создать?
1. Генераторное выражение: Просто замените квадратные скобки
Разница колоссальная! Генератор весит копейки, даже если в нем миллиард чисел.
2. Функция с
Если логика сложная, используем функцию. Вместо
🚀 Итог: Если вам не нужен доступ ко всем элементам сразу (например, по индексу
Знали про
📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
В прошлом посте мы восхищались списковыми включениями
[...]. Но у них есть фатальный недостаток: они создают весь список в памяти сразу.Представьте, что вам нужно обработать файл весом 10 ГБ. Если вы попытаетесь загрузить его в список
read_lines(), ваш компьютер скажет "Memory Error" и программа упадет. 💥Тут на помощь приходят Генераторы.
В чем отличие?
list): Хранит все элементы в памяти. Как готовая книга - все страницы уже напечатаны.Как создать?
1. Генераторное выражение: Просто замените квадратные скобки
[] на круглые ().
import sys
# Список (создает миллион чисел в памяти)
my_list = [x for x in range(1_000_000)]
print(f"List size: {sys.getsizeof(my_list)} bytes")
# ~8 000 000 байт (8 МБ)
# Генератор (просто формула)
my_gen = (x for x in range(1_000_000))
print(f"Gen size: {sys.getsizeof(my_gen)} bytes")
# ~100 байт (!!!)
Разница колоссальная! Генератор весит копейки, даже если в нем миллиард чисел.
2. Функция с
yield:Если логика сложная, используем функцию. Вместо
return (который убивает функцию и возвращает результат), пишем yield (который ставит на паузу и отдает значение).
def endless_numbers():
n = 0
while True: # Бесконечный цикл!
yield n
n += 1
# Можно брать по одному
gen = endless_numbers()
print(next(gen)) # 0
print(next(gen)) # 1
# Программа не зависнет, несмотря на while True
🚀 Итог: Если вам не нужен доступ ко всем элементам сразу (например, по индексу
list[10]), а вы просто перебираете их в цикле for - всегда используйте генераторы.Знали про
sys.getsizeof? Проверьте свои списки! 😉📲 Мы в MAX
Подписывайтесь на канал 👉@pythonofff
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3