Коллекции и структуры данных: вопросы для собеседования (часть 8)

Списки, словари, множества, кортежи — базовые структуры данных Python, без которых не обойтись ни в анализе, ни на собеседовании. Спрашивают про сложность операций, разницу между list и tuple, когда использовать set вместо list. Понимание коллекций показывает, что кандидат пишет эффективный код, а не просто «работающий».

Генераторы списков и встроенные функцииЦиклы и условияИсключения и отладкаРабота с файлами: JSON и CSVФункции и аргументыИтераторы и генераторыNumPy: основыPandas и DataFrameСинтаксис и типы данных

Вопросы 3640 из 40

36Начиная с Python 3.7 обычный `dict` тоже сохраняет порядок вставки. В каком случае `OrderedDict` из модуля `collections` всё ещё полезнее?
AКогда нужен `dict` с автоматической сортировкой ключей по алфавиту при каждой операции вставки нового элемента
BКогда нужен `dict` с лимитом на количество ключей и автоматическим вытеснением старых элементов из контейнера
CКогда нужен `dict`, запрещающий перезапись существующего ключа при выполнении присваивания `d[k] = v`
DКогда при сравнении через `==` важен порядок добавления ключей: `OrderedDict` его учитывает в равенстве
Ответ: `OrderedDict` учитывает порядок при сравнении: два `OrderedDict` с одинаковыми ключами в разном порядке не равны.

Обычный `dict` в Python 3.7+ сохраняет порядок вставки, но при сравнении через `==` порядок не учитывается: `{'a': 1, 'b': 2} == {'b': 2, 'a': 1}` вернёт `True`. Для `OrderedDict` порядок важен, и такие словари равными не будут. Также `OrderedDict` поддерживает метод `.move_to_end()`, которого у обычного `dict` нет.

Подробный разбор →
37Дан код:\n```python\nd = {'a': 1, 'b': 2}\nk = d.keys()\nd['c'] = 3\n```\nЧто будет в `k` после выполнения?
AВ `k` будет `dict_keys(['a', 'b', 'c'])`: динамическое представление словаря
BВ `k` будет `dict_keys(['a', 'b'])`: снимок ключей на момент вызова `.keys()`
CВ `k` будет пустой `dict_keys([])`: словарь был изменён сразу после вызова `.keys()`
DБудет выброшено исключение `RuntimeError`: словарь изменился после получения `dict_keys`
Ответ: `.keys()` возвращает динамическое представление, которое отражает текущее состояние словаря.

Объект `dict_keys`, возвращаемый `.keys()`, не копирует ключи, а ссылается на сам словарь. Поэтому после добавления нового ключа `'c'` представление `k` тоже покажет три ключа. То же самое касается `.values()` и `.items()`. Если нужен фиксированный снимок ключей, используйте `list(d.keys())`.

Подробный разбор →
38Вы хотите хранить координату точки как пару значений и использовать её как ключ в `dict`. Что обычно подходит лучше для самой координаты?
A`list`, потому что в нём легко менять элементы и добавлять новые координаты по мере поступления данных от пользователя
B`tuple`, потому что это неизменяемая пара значений и такой объект можно использовать как ключ в `dict` без потери позиции
C`set`, потому что он хранит только уникальные элементы и сам по себе ускоряет поиск ключей при работе с большими объёмами
D`dict` с двумя ключами `x` и `y`, потому что это тоже коллекция и подходит для хранения координат точки на плоскости
Ответ: Ключи в `dict` должны быть неизменяемыми; для пары значений с фиксированными позициями обычно выбирают `tuple`.

Если координата — фиксированная пара (например, `(x, y)` или `(lat, lon)`), `tuple` хорошо подходит: его нельзя случайно изменить, и такой объект можно использовать как ключ в `dict`. `list` изменяемый и поэтому плохо подходит для роли ключа. `set` не хранит порядок и вообще не предназначен для пары с фиксированными позициями. Вложенный `dict` с ключами `x` и `y` тоже нельзя использовать как ключ, потому что он изменяемый.

Подробный разбор →
39Дан код:\n```python\na = [[1, 2], [3, 4]]\nb = a.copy()\na[0].append(99)\n```\nБудет ли `99` в `b[0]`?
AВ `b[0]` тоже появится `99`: `.copy()` делает поверхностную копию, вложенные списки общие
BВ `b[0]` останется `[1, 2]` без изменений: метод `.copy()` рекурсивно копирует вложенные списки
CБудет исключение `TypeError` при `a[0].append(99)`: вложенный список после `.copy()` только для чтения
DВ исходном `a` ничего не изменится: `a[0].append(99)` создаст новый вложенный список вместо старого
Ответ: Метод `.copy()` создаёт поверхностную копию: внешний список новый, но вложенные объекты остаются теми же.

При поверхностной копии (`.copy()` или `list(a)`) создаётся новый внешний список, но его элементы — те же объекты. Поэтому `a[0]` и `b[0]` ссылаются на один и тот же вложенный список. Вызов `a[0].append(99)` модифицирует этот общий список, и `99` будет виден через `b[0]`. Для полной независимости используйте `copy.deepcopy(a)`, который рекурсивно копирует все вложенные объекты.

Подробный разбор →
40Есть функция `def f(x, y): return x + y` и словарь `d = {"x": 1, "y": 2}`. Что произойдёт при вызове `f(**d)`?
AПередаст словарь `d` целиком как один позиционный аргумент функции в неизменённом виде
BПередаст значения как именованные аргументы: эквивалентно записи `f(x=1, y=2)`
CПередаст ключи `'x'` и `'y'` как два позиционных строковых аргумента в порядке добавления
DПоднимет `TypeError` из-за того, что ключи словаря являются строками, а параметры функции ожидают число
Ответ: Оператор `**` при вызове функции распаковывает словарь в именованные аргументы: ключи становятся именами параметров.

Запись `f(**d)` эквивалентна `f(x=1, y=2)`. Ключи словаря должны совпадать с именами параметров функции и быть строками. Если в словаре есть ключ, которого нет в сигнатуре функции (и нет `**kwargs`), будет `TypeError`. Аналогично, `*` распаковывает список или кортеж в позиционные аргументы.

Подробный разбор →
12345678

Хотите тренировать интерактивно?

В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.

Тренировать Python в Telegram

Другие темы: Python

Генераторы списков и встроенные функцииЦиклы и условияИсключения и отладкаРабота с файлами: JSON и CSVФункции и аргументыИтераторы и генераторыNumPy: основыPandas и DataFrameСинтаксис и типы данных