Python: задачки и вопросы
7.51K subscribers
1.26K photos
1 video
1 file
116 links
Вопросы и задачки для подготовки к собеседованиям и прокачки навыков

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Другие наши проекты: https://tprg.ru/media
Download Telegram
Что выведет код? Перевод на новую строку и пробелы не учитываем, вопрос про списки.
Anonymous Quiz
55%
[1] [1, 1]
38%
[1] [1]
3%
[ ] [ ]
3%
[ ] [1]
1
В Python значения аргументов по умолчанию вычисляются один раз — при определении функции, а не при каждом вызове. Если использовать изменяемый объект (например, список) как аргумент по умолчанию, все вызовы функции без передачи значения будут работать с одним и тем же объектом.

В этом примере список 𝚡 создаётся при определении 𝚏𝚞𝚗, и каждый вызов 𝚏𝚞𝚗() добавляет в него единицу. Поэтому после первого вызова выводится [𝟷], а после второго уже [𝟷, 𝟷]. Такой эффект ловит многих: кажется, будто 𝚡 — новый пустой список при каждом вызове, но на деле это один и тот же, постоянно растущий список.​

Чтобы избежать такого поведения, используйте 𝙽𝚘𝚗𝚎 как значение по умолчанию — тогда новый список создаётся при каждом вызове:

𝚍𝚎𝚏 𝚏𝚞𝚗(𝚡=𝙽𝚘𝚗𝚎):
  𝚒𝚏 𝚡 𝚒𝚜 𝙽𝚘𝚗𝚎:
    𝚡 = [ ]
  𝚡.𝚊𝚙𝚙𝚎𝚗𝚍(𝟷)
  𝚛𝚎𝚝𝚞𝚛𝚗 𝚡

Теперь каждый раз будет новый список: [𝟷] — поведение ожидаемое и безопасное для задач, где нужны независимые коллекции.​

Эта особенность касается любых изменяемых типов: списков, словарей и даже пользовательских объектов. Полезно обратить на это внимание при проектировании функций‑инструментов и обработчиков.
4
Что выведет код в Python 3?
Anonymous Quiz
51%
['a', 'b', 'c'], 2
10%
['a', 'b', 'c'], 3
25%
['b', 'c'], 2
14%
Error
2👍1
Методы 𝚔𝚎𝚢𝚜(), 𝚟𝚊𝚕𝚞𝚎𝚜(), 𝚒𝚝𝚎𝚖𝚜() возвращают не списки, а динамические представления (views) словаря, которые автоматически обновляются при изменениях в оригинальном словаре.

Разбор по шагам:
🔘𝚍 = {'a': 10, 'b': 20} создаёт словарь с двумя парами.
🔘𝚔𝚎𝚢𝚜 = 𝚍.𝚔𝚎𝚢𝚜() возвращает 𝚍𝚒𝚌𝚝_𝚔𝚎𝚢𝚜(['a', 'b']) — представление ключей, отражающее текущее состояние 𝚍.
🔘𝚍['c'] = 30 добавляет новую пару; представление 𝚔𝚎𝚢𝚜 мгновенно видит три ключа, поэтому 𝚕𝚒𝚜𝚝(𝚔𝚎𝚢𝚜) даёт ['a', 'b', 'c'].
🔘𝚍.𝚙𝚘𝚙('a') удаляет ключ 'a'; представление снова обновляется, и теперь 𝚕𝚎𝚗(𝚔𝚎𝚢𝚜) возвращает 2 (остались 'b' и 'c').

Views — это не копии, а «живые» ссылки на словарь, экономящие память и время. В отличие от Python 2 (где 𝚍𝚒𝚌𝚝.𝚔𝚎𝚢𝚜() возвращал список-копию), в Python 3 представления всегда динамичны. Если бы код использовал 𝚕𝚒𝚜𝚝(𝚍.𝚔𝚎𝚢𝚜()) в начале, то 𝚘𝚕𝚍_𝚔𝚎𝚢𝚜 = 𝚕𝚒𝚜𝚝(𝚍.𝚔𝚎𝚢𝚜()), добавление 'c' не повлияло бы на 𝚘𝚕𝚍_𝚔𝚎𝚢𝚜 — оно осталось бы ['a', 'b'].
Please open Telegram to view this post
VIEW IN TELEGRAM
1
По умолчанию сортировка разных типов в Python 3 невозможна, но параметр key позволяет задать нормализацию данных. Ключ — кортеж (isinstance(x, str), int(x)): сначала сортируем по флагу «x — строка?» (False < True, значит числа идут раньше строк), затем по числовому значению int(x).

Разбор по шагам:
🔘Для 1 ключ (False, 1), для 2 — (False, 2). Для '3' — (True, 3), для '10' — (True, 10), для '20' — (True, 20).
🔘Сначала все элементы с False: 1, 2; затем True: '3', '10', '20'. Внутри групп сравнение по второму элементу ключа, то есть по числу после приведения.
🔘Поэтому результат — [1, 2, '3', '10', '20'].

Подводные камни:
🔘Без key будет TypeError, потому что числа и строки несравнимы.
🔘Если в данных встретится строка, не приводимая к int (например, 'x'), key упадёт с ValueError — для устойчивости можно использовать try/except в ключе или заранее фильтровать данные.

Вариант устойчивого ключа:

𝚍𝚎𝚏 𝚔(𝚡):
𝚝𝚛𝚢:
𝚛𝚎𝚝𝚞𝚛𝚗 (𝚒𝚜𝚒𝚗𝚜𝚝𝚊𝚗𝚌𝚎(𝚡, 𝚜𝚝𝚛), 𝚒𝚗𝚝(𝚡))
𝚎𝚡𝚌𝚎𝚙𝚝 𝚅𝚊𝚕𝚞𝚎𝙴𝚛𝚛𝚘𝚛:
𝚛𝚎𝚝𝚞𝚛𝚗 (𝚒𝚜𝚒𝚗𝚜𝚝𝚊𝚗𝚌𝚎(𝚡, 𝚜𝚝𝚛), 𝚏𝚕𝚘𝚊𝚝('𝚒𝚗𝚏'))
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2