PythonTalk
4.77K subscribers
1.45K photos
47 videos
7 files
1.32K links
Привет, меня зовут Олег Булыгин 👋

🐍 Здесь я делюсь полезной информацией для тех, кто пишет код на Python: от разработки до Data Science.

По вопросам: @obulygin91
Download Telegram
⚔️ Драма Python 2 vs Python 3 ⚔️

print "Hello" против print("Hello") — казалось бы, мелочь, но именно она стала одним из символов Великого Раскола, который на 10 лет погрузил Python-сообщество в настоящую гражданскую войну.

Почему Гвидо ван Россум (создатель Python) пошел на такой шаг? Что на самом деле сломалось, кроме print? И как этот конфликт, полный ожесточенных споров, багов и переписываний кода, сформировал тот Python, которым мы пользуемся сегодня?

Это не просто история обновления. Это сага о технических долгах, о сопротивлении сообщества и о том, как ради чистоты и будущего языка пришлось пожертвовать прошлым.

Историю «Великого Раскола», с примерами кода читайте в статье ◀️

#так_сложилось
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍3🔥311💯1
🐍 Алгоритмическая задачка

Представьте, что вы участвуете в карточном турнире 🃏. Перед вами на столе лежит ряд карт, каждая со своим номиналом. Правила просты, но требуют стратегического мышления.

Условие
Дан список очков card_points. За k ходов нужно набрать максимальную сумму очков. За один ход можно взять одну карту: либо самую левую, либо самую правую.

Функция должна принять список card_points и число k и вернуть максимально возможную сумму.

Примеры 👇

1️⃣ card_points = [1, 2, 3, 4, 5, 6, 1], k = 3
Вывод: 12
Пояснение: Оптимальная стратегия — взять три карты справа: 1, затем 6, затем 5. Сумма = 1 + 6 + 5 = 12.

2️⃣ card_points = [2, 2, 2], k = 2
Вывод: 4
Пояснение: Неважно, какие две карты взять, сумма всегда будет 4.

3️⃣ card_points = [9, 7, 7, 9, 7, 7, 9], k = 7
Вывод: 55
Пояснение: Мы должны забрать все карты, поэтому результат — это их общая сумма.

Жду ваши эффективные решения 🖥
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍2🙏1
3👍2🔥2🙏11
🗓Итоги месяца (август 2025)

🏆Топовый пост: бесплатный курс по deep learning от MIT 🎓

👀 Топ по просмотрам 👨🏻‍💻
1️⃣ Технические доклады из конференции «Code with Claude».
2️⃣ Релиз модельки Qwen Image.
3️⃣ Свежий отчёт «The State of Python 2025» от JetBrains.

📨 Топ по репостам 📥
1️⃣ MMORPG Artifacts, в которой можно писать скрипты для управления персонажами.
2️⃣ Как GPT-4o инвестирует на фондовом рынке.
3️⃣ Гайд по промптингу для программирования в GPT5 от OpenAI.

👍🏻 Топ по реакциям 😍
1️⃣ Как выбрать арбуз при помощи Python.
2️⃣ О том, что сейчас происходит в IT-найме.
3️⃣ Гайд по enumerate в Python.

#итоги_месяца
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3🎉2👍1🙏1👨‍💻1
🃏 Разбор карточной задачки: от O(k²) к O(k)!

Пришло время разобрать нашу задачу про карточный турнир.

🤔 Распространённый подход: полный перебор

Самая очевидная стратегия — перебрать все возможные комбинации взятых карт. Мы можем взять:
- k карт слева, 0 справа
- k-1 карт слева, 1 справа
- k-2 карт слева, 2 справа
- ...
- 0 карт слева, k карт справа

Этот подход абсолютно корректен. Однако, если реализовывать его "в лоб", на каждом шаге пересчитывая сумму срезов, код будет выглядеть примерно так:

def max_score_slow(card_points, k):
max_sum = 0
n = len(card_points)

for i in range(k + 1):
# i - сколько карт берем справа
# k-i - сколько карт берем слева
left_sum = sum(card_points[:k - i])
right_sum = sum(card_points[n - i:])
max_sum = max(max_sum, left_sum + right_sum)

return max_sum


Главный минус здесь — многократный вызов sum() внутри цикла. Каждая такая операция сама по себе занимает время, пропорциональное количеству элементов. В итоге общая сложность алгоритма получается O(k²), что может быть медленно на больших данных.


А можно ли быстрее? Конечно!


🚀 Эталонное решение: Скользящее окно за O(k)

Вместо того чтобы каждый раз пересчитывать сумму с нуля, мы можем вычислить её один раз, а затем "сдвигать" наш выбор, обновляя сумму за константное время O(1).

Как это работает?
1. Сначала считаем, что мы взяли первые k карт слева. Это наша первоначальная max_sum.
2. Затем в цикле k раз делаем "обмен": убираем одну карту с конца левой группы и добавляем одну карту справа.
3. На каждом шаге обновляем текущую сумму и сравниваем её с максимальной.

def max_score_fast(card_points, k):
n = len(card_points)

current_sum = sum(card_points[:k])
max_sum = current_sum

for i in range(1, k + 1):
# Обновляем сумму за O(1):
# отнимаем крайний левый элемент и прибавляем крайний правый
current_sum = current_sum - card_points[k - i] + card_points[n - i]
max_sum = max(max_sum, current_sum)

return max_sum


Время: O(k). Один начальный подсчет суммы sum(card_points[:k]) занимает O(k), и цикл также выполняется k раз с операциями за O(1).
💾 Память: O(1). Мы храним всего несколько переменных.


💡 Красивая альтернатива: инверсия задачи

Есть и другой, очень изящный способ взглянуть на проблему.

Вместо того чтобы максимизировать сумму k карт, которые мы берём, давайте минимизируем сумму n-k карт в центре, которые мы оставляем на столе.


Задача превращается в "найти непрерывный подмассив длиной n-k с минимальной суммой". Это тоже классическая задача на скользящее окно!

def max_score_inverted(card_points, k):
n = len(card_points)
window_size = n - k

total_sum = sum(card_points)

if window_size <= 0:
return total_sum

min_subarray_sum = current_sum = sum(card_points[:window_size])

for i in range(window_size, n):
current_sum += card_points[i] - card_points[i - window_size]
min_subarray_sum = min(min_subarray_sum, current_sum)

return total_sum - min_subarray_sum

Этот подход имеет сложность O(N), что тоже отлично. Он особенно хорош, когда k близко к N.

#алгособес
👍4🔥1🙏1