Что выведет код?
  class B:
def __init__(self) :
print ('В', end='')
super().__init__()
class C:
def __init__(self):
print('C', end='')
super().__init__ ()
class D(B, C):
def __init__(self):
print('D', end='')
B.__init__(self)
C.__init__(self)
X = D()
Выберите правильный вариант
  Anonymous Quiz
    5%
    DB
      
    2%
    DC
      
    65%
    DBC
      
    8%
    DBBC
      
    3%
    DBCC
      
    2%
    DCBC
      
    14%
    Посмотреть результаты
      
    Anonymous Quiz
    16%
    modify()
      
    8%
    append()
      
    8%
    extend()
      
    68%
    update()
      
    🧠 Хитрая Python-задача: «Генератор, который взламывает итераторы»  
Уровень: 💥 продвинутый (Python 3.12+)
Представьте, что у вас есть ленивый генератор, перебирающий огромный набор данных. Нужно «клонировать» итератор — создать копию, продолжающую работу с того же места, хотя обычные генераторы так не умеют.
🎯 Цель
Напишите
● Принимает любую функцию-генератор или итерируемый объект
● Возвращает объект с методом
● Позволяет параллельно вызывать
💡 Ограничения
● Нельзя полностью буферизовать всю последовательность
● Память O(k), где k — число активных клонов
● Только стандартная библиотека; асинхронность не требуется
🔍 Идея решения
● Храним значения в collections.deque по мере чтения из исходного итератора
● Для каждого клона ведём текущий индекс в буфере
● После сдвига всех клонов дальше минимальной позиции — удаляем хвост буфера
✅ Скелет реализации
📌 Пример использования
Попробуйте улучшить решение:
● Добавьте защиту от «зомби-клонов»
● Реализуйте __length_hint__()
● Или сделайте асинхронную версию acloneable() на базе async for
  Уровень: 💥 продвинутый (Python 3.12+)
Представьте, что у вас есть ленивый генератор, перебирающий огромный набор данных. Нужно «клонировать» итератор — создать копию, продолжающую работу с того же места, хотя обычные генераторы так не умеют.
🎯 Цель
Напишите
cloneable(generator), которая:● Принимает любую функцию-генератор или итерируемый объект
● Возвращает объект с методом
clone(), создающим независимую копию текущего состояния  ● Позволяет параллельно вызывать
next() у оригинала и всех клонов
gen = cloneable(range(100))
it1 = gen.clone()
it2 = gen.clone()
next(it1) # 0
next(it1) # 1
next(it2) # 0 ← независимая позиция
💡 Ограничения
● Нельзя полностью буферизовать всю последовательность
● Память O(k), где k — число активных клонов
● Только стандартная библиотека; асинхронность не требуется
🔍 Идея решения
● Храним значения в collections.deque по мере чтения из исходного итератора
● Для каждого клона ведём текущий индекс в буфере
● После сдвига всех клонов дальше минимальной позиции — удаляем хвост буфера
✅ Скелет реализации
from collections import deque
class CloneableIterator:
def __init__(self, iterable):
self._source = iter(iterable)
self._buffer = deque()
self._positions = []
def clone(self):
pos = 0
self._positions.append(pos)
idx = len(self._positions) - 1
def _iter():
nonlocal pos
while True:
if pos < len(self._buffer):
yield self._buffer[pos]
else:
try:
val = next(self._source)
except StopIteration:
return
self._buffer.append(val)
yield val
pos += 1
self._positions[idx] = pos
self._shrink()
return _iter()
def _shrink(self):
if not self._positions:
return
min_pos = min(self._positions)
for _ in range(min_pos):
self._buffer.popleft()
self._positions = [p - min_pos for p in self._positions]
def cloneable(iterable):
return CloneableIterator(iterable)
📌 Пример использования
gen = cloneable(i**2 for i in range(5))
a = gen.clone()
b = gen.clone()
print(next(a)) # 0
print(next(a)) # 1
print(next(b)) # 0
print(next(b)) # 1
print(next(b)) # 4
Попробуйте улучшить решение:
● Добавьте защиту от «зомби-клонов»
● Реализуйте __length_hint__()
● Или сделайте асинхронную версию acloneable() на базе async for
🐍 Python-задача: что выведет этот код и почему?
🔍 Варианты:
• a)
• b)
• c) Ошибка исполнения
• d)
💡 Разбор:
Аргумент   — изменяемый объект, созданный один раз при компиляции функции, а не каждый раз при вызове. Поэтому:
- Первый вызов:  → добавили   →    
- Второй вызов: та же , теперь   → добавили   →    
- Третий: тот же список → 
✅ Правильный ответ: b) `[1]`, `[1, 2]`, `[1, 2, 3]`
🧠 Вывод: никогда не используй изменяемые значения (`list`,, `set`) в аргументах по умолчанию. Это одна из самых частых ловушек в Python.
🛠️ Правильный способ: 
📌 Теперь каждый вызов будет работать с новым списком.
  
def append_to_list(value, my_list=[]):
my_list.append(value)
return my_list
print(append_to_list(1))
print(append_to_list(2))
print(append_to_list(3))
🔍 Варианты:
• a)
[1], [2], [3]  • b)
[1], [1, 2], [1, 2, 3]  • c) Ошибка исполнения
• d)
[1], [2], [3] — но в разных объектах💡 Разбор:
my_list=[]- Первый вызов:
my_list = []1[1]- Второй вызов: та же
my_list[1]2[1, 2]- Третий: тот же список →
[1, 2, 3]✅ Правильный ответ: b) `[1]`, `[1, 2]`, `[1, 2, 3]`
🧠 Вывод: никогда не используй изменяемые значения (`list`,
dict🛠️ Правильный способ:
def append_to_list(value, my_list=None):
if my_list is None:
my_list = []
my_list.append(value)
return my_list
📌 Теперь каждый вызов будет работать с новым списком.
Forwarded from Python/ django
🐍 Python-задача: что выведет этот код с вложенными генераторами?
🔍 Варианты:
• a)
• b)
• c)
• d)
💡 Разбор:
- `gen = (x for x in range(3))` — генератор 0, 1, 2  
- `wrap(gen)` — создаёт **новый генератор**, который берёт значения из `gen` и умножает на 2
Но генераторы **исчерпаемы**: после первого полного прохода `list(gen)` → `gen` становится пустым
Значит:
- `list(gen)` → `[0, 1, 2]`
- `gen2 = wrap(gen)` теперь ссылается на **пустой** `gen`
- `list(gen2)` → `[]`
✅ **Правильный ответ: b) `[0, 1, 2]`, `[]`**
🧠 **Вывод:** если оборачиваешь генератор — не "прожигай" его до передачи дальше. Генераторы нельзя перезапустить или "перемотать".
🛠️ Совет: если данные нужны повторно — сохрани их в список:
``` python
data = list(gen)
```
или используй   для разветвления итератора.
 @pythonl
  
gen = (x for x in range(3))
def wrap(g):
return (x * 2 for x in g)
gen2 = wrap(gen)
print(list(gen))
print(list(gen2))
🔍 Варианты:
• a)
[0, 1, 2], [0, 2, 4]  • b)
[0, 1, 2], []  • c)
[], [0, 2, 4]  • d)
[0, 1, 2], Ошибка💡 Разбор:
- `wrap(gen)` — создаёт **новый генератор**, который берёт значения из `gen` и умножает на 2
Но генераторы **исчерпаемы**: после первого полного прохода `list(gen)` → `gen` становится пустым
Значит:
- `list(gen)` → `[0, 1, 2]`
- `gen2 = wrap(gen)` теперь ссылается на **пустой** `gen`
- `list(gen2)` → `[]`
✅ **Правильный ответ: b) `[0, 1, 2]`, `[]`**
🧠 **Вывод:** если оборачиваешь генератор — не "прожигай" его до передачи дальше. Генераторы нельзя перезапустить или "перемотать".
🛠️ Совет: если данные нужны повторно — сохрани их в список:
```
data = list(gen)
```
itertools.teeЧто выведет код?
  Anonymous Quiz
    7%
    0 + ziuq
      
    25%
    0.0 + ziuq
      
    6%
    0.0 + 0
      
    8%
    -0.0 + ''
      
    9%
    0.0 + ''
      
    45%
    Error
      
    This media is not supported in your browser
    VIEW IN TELEGRAM
  ⚙️ Подменяй любые импорты в Python “на лету” — без изменения кода
Если ты хочешь протестировать модуль, подменить зависимость, замокать внешний сервис или обмануть импорт — не обязательно редактировать исходники. Python позволяет перехватывать импорты прямо во время выполнения, через
Вот минимальный приём, который делает это прозрачно:
  Если ты хочешь протестировать модуль, подменить зависимость, замокать внешний сервис или обмануть импорт — не обязательно редактировать исходники. Python позволяет перехватывать импорты прямо во время выполнения, через
sys.modules.Вот минимальный приём, который делает это прозрачно:
import sys
import types
# Создаём фейковый модуль
fake = types.SimpleNamespace()
fake.get_data = lambda: "подмена работает"
# Подменяем импорт
sys.modules['external_service'] = fake
# Теперь даже import будет работать
import external_service
print(external_service.get_data()) # → "подмена работает"
🧠 Хитрая задача по Python — что не так с set и списками?
Задача:
Вы хотите получить уникальные элементы из вложенных списков:
Что произойдёт?
Варианты ответа:
1. Выведется:
2. Выведется:
3. Произойдёт ошибка
4. Все вложенные списки преобразуются в кортежи и выведутся без дубликатов
Правильный ответ:
💥
🔍 Разбор
В Python элементы
То есть:
✅ Как сделать правильно?
Если вы хотите получить уникальные вложенные списки, можно преобразовать их в кортежи:
А если хочется вернуть результат обратно в список списков:
⚠️ Вывод
-
- Используйте
- Уникальность вложенных списков — частый источник багов при работе с JSON, DataFrame, API
📌 Такие мелочи легко упустить, но они выстреливают в самых неожиданных местах. Подписывайся, чтобы не наступать на грабли в одиночку.
  Задача:
Вы хотите получить уникальные элементы из вложенных списков:
items = [[1, 2], [3, 4], [1, 2]]
unique = set(items)
print(unique)
Что произойдёт?
Варианты ответа:
1. Выведется:
{[1, 2], [3, 4]}  2. Выведется:
[[1, 2], [3, 4]]  3. Произойдёт ошибка
4. Все вложенные списки преобразуются в кортежи и выведутся без дубликатов
Правильный ответ:
3. Произойдёт ошибка💥
TypeError: unhashable type: 'list'🔍 Разбор
В Python элементы
set должны быть хешируемыми. А списки — изменяемый тип данных, следовательно, не хешируемы.То есть:
set([[1, 2], [3, 4]])
# ❌ вызовет ошибку
✅ Как сделать правильно?
Если вы хотите получить уникальные вложенные списки, можно преобразовать их в кортежи:
items = [[1, 2], [3, 4], [1, 2]]
unique = set(tuple(x) for x in items)
print(unique) # {(1, 2), (3, 4)}
А если хочется вернуть результат обратно в список списков:
result = [list(x) for x in unique]
print(result) # [[1, 2], [3, 4]] (порядок не гарантирован)
⚠️ Вывод
-
list нельзя положить в set, dict как ключ — они unhashable- Используйте
tuple для таких случаев- Уникальность вложенных списков — частый источник багов при работе с JSON, DataFrame, API
📌 Такие мелочи легко упустить, но они выстреливают в самых неожиданных местах. Подписывайся, чтобы не наступать на грабли в одиночку.
Forwarded from Python/ django
def append_to_list(val, my_list=[]):
my_list.append(val)
return my_list
print(append_to_list(1))
print(append_to_list(2))
print(append_to_list(3))
🤯 Подвох
Многие думают, что каждый вызов append_to_list() создаёт новый список, и ожидают вывод:
[1]
[2]
[3]
Но на самом деле Python выведет:
[1]
[1, 2]
[1, 2, 3]
🧠 Почему так происходит?
В Python значения аргументов по умолчанию вычисляются один раз — при определении функции, а не при каждом вызове.
Значение my_list=[] создаётся один раз и сохраняется между вызовами. Это работает как статическая переменная внутри функции.
✅ Как это исправить?
Используй None как значение по умолчанию:
def append_to_list(val, my_list=None):
if my_list is None:
my_list = []
my_list.append(val)
return my_list
print(append_to_list(1)) # [1]
print(append_to_list(2)) # [2]
print(append_to_list(3)) # [3]
💡 Вывод
Не используйте изменяемые объекты (например, list, dict, set) как значения по умолчанию для аргументов функций в Python.
@pythonl
Please open Telegram to view this post
    VIEW IN TELEGRAM
  Каким будет вывод этого кода в консоли?
  Anonymous Quiz
    7%
    {1, 2}
      
    39%
    True
      
    17%
    False
      
    30%
    Это невозможная операция
      
    7%
    Посмотреть ответ
      
    Каким будет вывод этого кода?
  Anonymous Quiz
    5%
    5 5 6
      
    38%
    5 6 7
      
    41%
    5 5 6 7 7 7
      
    2%
    5 6 7 7 7
      
    13%
    Посмотреть ответ
      
    This media is not supported in your browser
    VIEW IN TELEGRAM
  Что выведет следующий код — и почему?
a = 256
b = 256
print(a is b)
x = 257
y = 257
print(x is y)
❓Ожидаешь True в обоих случаях? Не всё так просто.
📌 В Python целые числа от -5 до 256 кешируются.
То есть a и b указывают на один и тот же объект → a is b → True
Но x и y — это уже разные объекты, потому что 257 не кешируется → x is y → False
⚠️ is сравнивает объекты, а не значения.
Если хочешь сравнить значения — используй ==
💡 Вывод: даже базовые типы могут вести себя неожиданно, если сравнивать их через is.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  Каким будет вывод этого кода?
  Anonymous Quiz
    31%
    ('we', 'are', 'humans')
      
    14%
    (we, are, humans)
      
    7%
    ('we', 'humans')
      
    21%
    'we are humans'
      
    26%
    Посмотреть ответ
      
    