Python tests
الذهاب إلى القناة على Telegram
Тесты и задания python разработчиков По всем вопросам- @notxxx1 @ai_machinelearning_big_data - машинное обучение @programming_books_it - бесплатные it книги @pythonl - 🐍 @ArtificialIntelligencedl - AI @datascienceiot -ds книги
إظهار المزيد6 938
المشتركون
-424 ساعات
-127 أيام
-5630 أيام
أرشيف المشاركات
6 937
Repost 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.
@pythonl6 937
🧠 Хитрая задача по Python — что не так с set и списками?
Задача:
Вы хотите получить уникальные элементы из вложенных списков:
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
📌 Такие мелочи легко упустить, но они выстреливают в самых неожиданных местах. Подписывайся, чтобы не наступать на грабли в одиночку.6 937
⚙️ Подменяй любые импорты в 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()) # → "подмена работает"6 937
Repost from Python/ django
🐍 Python-задача: что выведет этот код с вложенными генераторами?
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], Ошибка
💡 Разбор:
- `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)
```
или используй itertools.tee для разветвления итератора.
@pythonl6 937
🐍 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, `set`) в аргументах по умолчанию. Это одна из самых частых ловушек в Python.
🛠️ Правильный способ:
def append_to_list(value, my_list=None):
if my_list is None:
my_list = []
my_list.append(value)
return my_list
📌 Теперь каждый вызов будет работать с новым списком.6 937
🧠 Хитрая Python-задача: «Генератор, который взламывает итераторы»
Уровень: 💥 продвинутый (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 for6 937
🤔 Какой метод используется для обновления нескольких ключей и значений в словаре?
6 937
Что выведет код?
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()6 937
Какой из следующих методов НЕ является методом перегрузки операций в Python?
6 937
🐍 Хитрая задача на Python с подвохом
📌 Задача:
Ты пишешь функцию
track, которая возвращает список всех значений, которые в неё передавали. Пример поведения:
print(track(1)) # [1]
print(track(2)) # [1, 2]
print(track(3)) # [1, 2, 3]
Реализуй эту функцию.
🎯 Подвох:
- Решение работает без глобальных переменных
- Используется поведение изменяемых аргументов по умолчанию
- Это поведение часто становится причиной багов у новичков — но здесь оно работает на нас
---
✅ Ожидаемый результат:
def track(value, cache=[]):
cache.append(value)
return cache
# Проверка:
print(track(1)) # [1]
print(track(2)) # [1, 2]
print(track(3)) # [1, 2, 3]
🧠 Объяснение подвоха:
- Аргумент cache=[] вычисляется один раз, при первом вызове функции
- Все последующие вызовы используют один и тот же список
- Обычно это считается "ловушкой", но в задачах на замыкание состояния — это полезный трюк
⚠️ Не путай: если внутри функции ты напишешь cache = [], то всё сломается — потому что создастся новый список каждый раз
متاح الآن! بحث تيليغرام 2025 — أهم رؤى العام 
