Коллекции и структуры данных: вопросы для собеседования (часть 4)
Списки, словари, множества, кортежи — базовые структуры данных Python, без которых не обойтись ни в анализе, ни на собеседовании. Спрашивают про сложность операций, разницу между list и tuple, когда использовать set вместо list. Понимание коллекций показывает, что кандидат пишет эффективный код, а не просто «работающий».
Вопросы 16–20 из 40
16Дан список `nums = [10, 20, 1, 30]`. Чем отличаются `nums.remove(1)` и `del nums[1]`?
A`.remove(1)` удаляет значение `1`, а `del nums[1]` удаляет элемент по индексу `1`, то есть `20`
B`.remove(1)` удаляет элемент по индексу `1`, то есть `20`, а `del nums[1]` ищет значение `1`
C`del nums[1]` удаляет первое вхождение значения `1`, а `.remove(1)` удаляет элемент по индексу `1`
DОба вызова делают одно и то же: удаляют элемент `20` по индексу `1` из списка `nums`
Ответ: `.remove(x)` ищет и удаляет первое вхождение значения `x`, а `del lst[i]` удаляет элемент по индексу `i`.
`nums.remove(1)` находит первое вхождение числа `1` (индекс 2) и удаляет его, оставив `[10, 20, 30]`. А `del nums[1]` удаляет элемент с индексом 1 (число `20`), оставив `[10, 1, 30]`. Путаница возникает, когда значение совпадает с допустимым индексом. Если значения нет, `.remove()` выбросит `ValueError`.
Подробный разбор → 17Даны множества пользователей `a` и `b`. Как получить пользователей, которые есть одновременно в обоих множествах?
A`a | b`
B`a - b`
C`a & b`
D`a + b`
Ответ: Пересечение множеств — оператор `&`.
Для `set` есть базовые операции: объединение `a | b`, пересечение `a & b` и разность `a - b`. Пересечение возвращает элементы, которые присутствуют в обоих множествах, что часто используется для анализа пересекающихся аудиторий.
Подробный разбор → 18Есть список событий `events = ["click"]`. Объект `events` используется в нескольких местах по ссылке, поэтому важно изменить именно тот же объект (не создавать новый). Нужно добавить элементы из `new_events = ["view", "purchase"]`, чтобы итог был плоским. Какой вариант корректен?
A`events.extend(new_events)`
B`events.append(new_events)`
C`events = events + new_events`
D`events.update(new_events)`
Ответ: Метод `.extend()` добавляет элементы из итерируемого объекта в конец списка и меняет его на месте, не создавая новый объект.
Чтобы сохранить тот же объект списка (например, на него есть другие ссылки), нужен `.extend()`: он добавит каждый элемент из `new_events` в `events`. Метод `.append()` положит сам список как один элемент и получится вложенный список. Выражение `events = events + new_events` создаёт новый объект и перепривязывает имя `events`, поэтому другие ссылки на старый список изменений не увидят. Метода `.update()` у списка нет — это метод словаря и множества.
Подробный разбор → 19Нужно хранить соответствие `user_id` → число покупок и обновлять счётчик при каждой покупке. Какая коллекция Python подходит лучше всего?
A`list`: упорядоченная коллекция с доступом по позиции без удобной привязки к идентификатору
B`set`: коллекция уникальных ключей без значений, не позволяет хранить счётчик
C`dict`: пары ключ → значение, где `user_id` выступает ключом, а значение — счётчик
D`tuple`: неизменяемая коллекция фиксированной длины без обновления значений
Ответ: `dict` хранит пары ключ → значение и подходит для словарей-счётчиков.
`list` и `tuple` ориентированы на доступ по позиции, а не по идентификатору, и не дают O(1)-доступ к произвольному пользователю. `set` хранит только ключи без значений, поэтому посчитать количество покупок в нём нельзя. Для задачи «по `user_id` хранить и обновлять число покупок» естественный выбор — `dict`, где ключом выступает `user_id`, а значением — счётчик.
Подробный разбор → 20Есть словарь настроек `config = {"timeout": 5, "retries": 2}` и словарь переопределений `override = {"timeout": 10}`. Как обновить `config`, чтобы применить переопределения и сохранить остальные ключи?
A`config + override`: оператор сложения возвращает новый словарь с объединёнными ключами
B`config.update(override)`: метод обновляет исходный словарь значениями переопределений
C`override.update(config)`: метод обновляет словарь переопределений значениями исходного
D`config.append(override)`: метод вставляет словарь переопределений как новый элемент
Ответ: Метод `dict.update(...)` обновляет словарь значениями из другого словаря по совпадающим ключам.
Вызов `config.update(override)` заменит значение по ключу `"timeout"` на 10 и добавит новые ключи, если они есть в `override`. Вариант `override.update(config)` меняет другой словарь и не подходит, если цель — обновить именно `config`. Оператор `+` к словарям неприменим, а метода `.append` у словарей нет — он работает у списков и вставляет элемент целиком.
Подробный разбор →