Перейти к содержимому
На этой странице

Типы и коллекции Python

Все темы Data Analyst

Подтемы:

В чем разница между списком и кортежем?

Основные различия между списком и кортежем в Python:

  1. Изменяемость:

    • Список (list): изменяемый (можно добавлять, удалять или изменять элементы).

    • Кортеж (tuple): неизменяемый (после создания элементы изменить нельзя).

  2. Синтаксис:

    • Список: создается с помощью квадратных скобок [].

      my_list = [1, 2, 3]
    • Кортеж: создается с помощью круглых скобок ().

      my_tuple = (1, 2, 3)
  3. Производительность:

    • Кортеж: обычно имеет немного более высокую производительность из-за неизменяемости.
  4. Использование:

    • Список: используется, когда нужно часто изменять содержимое.

    • Кортеж: используется для хранения неизменяемых данных или когда нужно гарантировать, что данные не будут изменены.


В чем разница между “is” и “==”?

Основные различия между операторами is и == в Python:

  1. Сравнение объектов:

    • is: проверяет, ссылаются ли две переменные на один и тот же объект в памяти (т.е. проверяет идентичность объектов).

      a = [1, 2, 3]
      b = a
      print(a is b)  # True
    • ==: проверяет, равны ли значения двух объектов (т.е. проверяет равенство значений).

      a = [1, 2, 3]
      b = [1, 2, 3]
      print(a == b)  # True
      print(a is b)  # False

Переменные в Python передаются по ссылке или по значению?

При вызове функции параметры связываются с переданными объектами. Автоматического копирования нет ни для изменяемых, ни для неизменяемых объектов. Изменение переданного списка видно снаружи, а присваивание параметру нового объекта меняет только локальную привязку имени.

Примеры:

  1. Изменяемые объекты:

    def modify_list(lst):
        lst.append(4)
    
    my_list = [1, 2, 3]
    modify_list(my_list)
    print(my_list)  # [1, 2, 3, 4]
  2. Неизменяемые объекты:

    def modify_number(n):
        n += 1
    
    my_number = 10
    modify_number(my_number)
    print(my_number)  # 10

Назовите изменяемые и неизменяемые объекты

Изменяемые объекты:

  1. Список (list)

  2. Словарь (dict)

  3. Множество (set)

  4. Массивы из библиотеки numpy (например, numpy.array)

Неизменяемые объекты:

  1. Числа (int, float, complex)

  2. Строки (str)

  3. Кортежи (tuple)

  4. Неизменяемые множества (frozenset)

  5. Булевы значения (bool)


Как развернуть список?

В Python список можно развернуть несколькими способами:

  1. Используя срезы: Это наиболее простой и часто используемый способ.

    my_list = [1, 2, 3, 4, 5]
    reversed_list = my_list[::-1]
  2. С помощью метода reverse(): Этот метод изменяет список на месте, не создавая новый.

    my_list = [1, 2, 3, 4, 5]
    my_list.reverse()
  3. С использованием функции reversed() : Эта функция возвращает итератор, который возвращает элементы списка в обратном порядке.

    my_list = [1, 2, 3, 4, 5]
    reversed_list = list(reversed(my_list))

Срез и list(reversed(…)) создают новый список. Метод reverse() изменяет исходный список и возвращает None; reversed() сам по себе возвращает итератор.


Как работает умножение списка?

Умножение списка в Python создает новый список, повторяя исходный список заданное количество раз.

Пример:

my_list = [1, 2, 3]
result = my_list * 3
print(result)  # [1, 2, 3, 1, 2, 3, 1, 2, 3]

В этом примере список my_list умножается на 3, что приводит к созданию нового списка result, который содержит элементы my_list, повторенные три раза подряд.


Как объединить списки в Python?

В Python списки можно объединить несколькими способами:

  1. Используя оператор +:

    list1 = [1, 2, 3]
    list2 = [4, 5, 6]
    combined_list = list1 + list2
  2. Используя метод extend():

    list1 = [1, 2, 3]
    list2 = [4, 5, 6]
    list1.extend(list2)
  3. Используя списковое выражение:

    list1 = [1, 2, 3]
    list2 = [4, 5, 6]
    combined_list = list1 + list2

Оператор + создаёт новый список, а extend() изменяет исходный список на месте и возвращает None.


В чем разница между глубокой и мелкой копиями?

Разница между глубокой и мелкой копиями в Python связана с тем, как копируются вложенные структуры данных, такие как списки или словари:

Мелкая копия ( shallow copy ):

  • Создается новый объект, но вложенные объекты остаются ссылками на оригинальные объекты.

  • Изменения вложенных объектов в копии будут отражены в оригинале.

  • Для создания мелкой копии можно использовать метод .copy() у списка или словаря или функцию copy.copy() из модуля copy.

Пример мелкой копии списка:

import copy

list1 = [1, [2, 3]]
list2 = copy.copy(list1)

list2[1][0] = 4
print(list1)  # [1, [4, 3]]
print(list2)  # [1, [4, 3]]

Глубокая копия ( deep copy ):

  • Создается новый объект и рекурсивно копируются все вложенные объекты.

  • Изменения в глубокой копии не влияют на оригинал и наоборот.

  • Для создания глубокой копии можно использовать функцию copy.deepcopy() из модуля copy.

Пример глубокой копии списка:

import copy

list1 = [1, [2, 3]]
list2 = copy.deepcopy(list1)

list2[1][0] = 4
print(list1)  # [1, [2, 3]]
print(list2)  # [1, [4, 3]]

Таким образом, при работе с изменяемыми вложенными структурами данных важно понимать разницу между мелкой и глубокой копиями для предотвращения неожиданных побочных эффектов.


В чем разница между списками и массивами?

Основные различия между списками (list) и массивами в контексте Python:

  1. Использование:

    • Списки (list): универсальная структура данных, которая может содержать элементы различных типов и изменяться в размере.

    • Массивы: в Python обычно используются массивы из библиотеки numpy (numpy.array). Они предназначены для работы с числовыми данными и обеспечивают эффективные операции над большими объемами данных.

  2. Типы данных:

    • Списки (list): могут содержать элементы различных типов данных (например, числа, строки, другие списки и т.д.).

    • Массивы: обычно содержат элементы одного типа данных (например, только числа типа float или int).

  3. Производительность:

    • Массивы: операции с массивами из numpy обычно выполняются более эффективно благодаря оптимизированным внутренним реализациям.

    • Списки (list): менее эффективны для числовых вычислений из-за динамической природы и возможности хранения различных типов данных.

  4. Изменяемость:

    • Оба типа данных в Python изменяемы и могут изменяться в размере, однако массивы numpy предпочтительны для операций, которые требуют изменения больших объемов данных из-за своей эффективной реализации и оптимизации.

Как объединить два массива?

В Python, особенно если речь идет о массивах из библиотеки NumPy, для объединения двух массивов можно использовать функцию numpy.concatenate() или оператор + для списков (если мы говорим о стандартных списках Python):

  1. Для списков (стандартных массивов в Python):

    array1 = [1, 2, 3]
    array2 = [4, 5, 6]
    combined_array = array1 + array2
  2. Для массивов NumPy:

    import numpy as np
    
    array1 = np.array([1, 2, 3])
    array2 = np.array([4, 5, 6])
    combined_array = np.concatenate((array1, array2))

В обоих случаях combined_array будет содержать объединенные элементы array1 и array2.


Что такое срезы списка? Как их делать?

Срезы списка в Python позволяют извлекать подмножество элементов из списка по заданным индексам. Они делаются с использованием синтаксиса [start:stop:step], где:

  • start: начальный индекс (включительно), с которого начинается срез (по умолчанию 0).

  • stop: конечный индекс (исключительно), на котором заканчивается срез (по умолчанию длина списка).

  • step: шаг (по умолчанию 1), определяющий интервал между выбранными элементами.

Примеры использования срезов:

my_list = [1, 2, 3, 4, 5]

# Получение элементов с индексами от 1 до 3 (не включая 3)
slice1 = my_list[1:3]
# slice1 = [2, 3]

# Получение элементов с индексами от 0 до 4 с шагом 2
slice2 = my_list[0:4:2]
# slice2 = [1, 3]

# Получение элементов с индексами от 2 до конца списка
slice3 = my_list[2:]
# slice3 = [3, 4, 5]

# Получение элементов с индексами от начала до 3 (не включая 3)
slice4 = my_list[:3]
# slice4 = [1, 2, 3]

# Получение элементов с индексами в обратном порядке
slice5 = my_list[::-1]
# slice5 = [5, 4, 3, 2, 1]

Как работают any() и all()?

Функции any() и all() в Python предназначены для работы с итерируемыми объектами (например, списками, кортежами) и возвращают булевое значение True или False в зависимости от условий:

  1. any(iterable):

    • Возвращает True, если хотя бы один элемент в итерируемом объекте истинный (не равен False, 0, None или пустой объект).

    • Если все элементы ложные, возвращает False.

    Пример:

    list1 = [True, False, True]
    result = any(list1)
    print(result)  # Вывод: True
  2. all(iterable):

    • Возвращает True, если все элементы в итерируемом объекте истинные (не равны False, 0, None или пусты).

    • Если хотя бы один элемент ложный, возвращает False.

    Пример:

    list2 = [True, True, False]
    result = all(list2)
    print(result)  # Вывод: False

Обе функции полезны для проверки условий в списке или других структурах данных, где требуется быстро выяснить, содержит ли объект хотя бы одно истинное или все элементы истинные.


Как удалить из списка дубликаты?

Для удаления дубликатов из списка в Python можно использовать несколько подходов. Вот два основных способа:

  1. С использованием типа данных set:

    • Преобразовать список в множество (set), так как множество автоматически удаляет дубликаты.

    • Преобразуйте множество обратно в список, если нужен результат типа list. Исходный порядок при этом не восстанавливается.

    my_list = [1, 2, 2, 3, 4, 4, 5]
    unique_items = list(set(my_list))

    Этот метод прост и эффективен, однако не сохраняет порядок элементов изначального списка.

  2. С использованием списка и цикла:

    • Создать новый список и добавлять в него элементы из исходного списка, если они еще не встречались.
    my_list = [1, 2, 2, 3, 4, 4, 5]
    unique_items = []
    for item in my_list:
        if item not in unique_items:
            unique_items.append(item)

    Этот метод сохраняет порядок элементов, но менее эффективен по времени выполнения, особенно для больших списков.

Выбор метода зависит от конкретной задачи: использование множества (set) предпочтительно для простого удаления дубликатов, если порядок не важен, в то время как цикл и проверка позволяют сохранить порядок элементов, но могут быть менее эффективными.


В чем разница между append и extend?

Разница между методами append() и extend() в Python заключается в способе добавления элементов в конец списка:

  1. append():

    • Добавляет элемент в конец списка как один элемент.

    • Принимает один аргумент, который может быть любым типом данных (число, строка, объект и т.д.).

    Пример:

    my_list = [1, 2, 3]
    my_list.append(4)
    print(my_list)  # Вывод: [1, 2, 3, 4]
  2. extend():

    • Расширяет список, добавляя элементы из итерируемого объекта (например, другого списка) в конец текущего списка.

    • Принимает один аргумент, который должен быть итерируемым объектом (список, кортеж, строка и т.д.).

    Пример:

    my_list = [1, 2, 3]
    another_list = [4, 5, 6]
    my_list.extend(another_list)
    print(my_list)  # Вывод: [1, 2, 3, 4, 5, 6]

Таким образом, append() добавляет один элемент в конец списка, а extend() добавляет элементы из другого итерируемого объекта в конец текущего списка, расширяя его.


В чем разница между remove, del и pop?

В Python есть три основных способа удаления элементов из списка, каждый из которых имеет свои особенности:

  1. remove():

    • Удаляет первое вхождение указанного значения из списка.

    • Если значение не найдено, возникает ошибка ValueError.

    Пример:

    my_list = [1, 2, 3, 2]
    my_list.remove(2)
    print(my_list)  # Вывод: [1, 3, 2]
  2. del:

    • Удаляет элемент по индексу или срезу.

    • Не возвращает значение элемента.

    • Позволяет удалить несколько элементов за раз, используя срезы.

    Пример удаления элемента по индексу:

    my_list = [1, 2, 3]
    del my_list[1]
    print(my_list)  # Вывод: [1, 3]

    Пример удаления элементов с использованием среза:

    my_list = [1, 2, 3, 4, 5]
    del my_list[1:3]
    print(my_list)  # Вывод: [1, 4, 5]
  3. pop():

    • Удаляет элемент по индексу и возвращает его значение.

    • Если индекс не указан, удаляется и возвращается последний элемент списка.

    Пример удаления и получения значения элемента по индексу:

    my_list = [1, 2, 3]
    popped_value = my_list.pop(1)
    print(my_list)      # Вывод: [1, 3]
    print(popped_value) # Вывод: 2

Как выполняется интерполяция строк?

Интерполяция строк в Python выполняется несколькими способами:

  1. f-строки (форматированные строковые литералы):

    name = "Alice"
    age = 30
    result = f"My name is {name} and I am {age} years old."
  2. Метод .format():

    name = "Alice"
    age = 30
    result = "My name is {} and I am {} years old.".format(name, age)
  3. Оператор %:

    name = "Alice"
    age = 30
    result = "My name is %s and I am %d years old." % (name, age)

Все эти способы позволяют вставлять значения переменных в строки.


Как работает умножение строк?

Умножение строк в Python повторяет строку указанное количество раз. Используется оператор *.

Пример:

text = "Hello"
result = text * 3
print(result)  # "HelloHelloHello"

Этот код создает новую строку, состоящую из трех повторений строки text.


Какая разница между словарями и JSON?

Основные различия между словарями в Python и JSON (JavaScript Object Notation):

  1. Синтаксис и представление:

    • Словарь dict в Python хранит пары ключ-значение и сохраняет порядок вставки ключей. Ключи должны быть хешируемыми; равные ключи обозначают одну запись.

    • JSON: это текстовый формат для представления структурированных данных, состоящий из пар ключ-значение, аналогично словарям в Python. Он используется для обмена данными между различными платформами и является более универсальным.

  2. Использование:

    • Словари в Python: используются внутри программы для организации и обработки данных.

    • JSON: часто используется для передачи данных между клиентом и сервером или для сохранения данных в файлы, когда требуется обмен информацией между различными языками программирования.

  3. Поддержка типов данных:

    • Словарь допускает значения любых типов, а ключи только хешируемых типов. Например, список может быть значением, но не ключом.

    • JSON: поддерживает ограниченный набор базовых типов данных, таких как строки, числа, логические значения, массивы и объекты. Например, словари в Python могут содержать кортежи, а JSON — нет.

  4. Дополнительные особенности JSON:

    • JSON: форматизирован для легкости восприятия человеком, что делает его удобным для чтения и написания.

Как отсортировать словарь по ключам, в алфавитном порядке?

Для сортировки словаря по ключам в алфавитном порядке в Python можно использовать функцию sorted() вместе с методом .items() словаря для получения списка кортежей (ключ, значение), отсортированных по ключам. Вот как это делается:

my_dict = {'c': 1, 'a': 2, 'b': 3}

sorted_dict = dict(sorted(my_dict.items()))

print(sorted_dict)  # Вывод: {'a': 2, 'b': 3, 'c': 1}

В этом примере sorted(my_dict.items()) возвращает отсортированный список кортежей ('a', 2), ('b', 3), ('c', 1). Затем функция dict() используется для преобразования отсортированного списка кортежей обратно в словарь.


Как округлить число до трех десятичных знаков?

Для округления числа до трех десятичных знаков в Python можно использовать функцию round() с указанием количества знаков после запятой:

number = 3.14159265359
rounded_number = round(number, 3)
print(rounded_number)  # Вывод: 3.142

В этом примере round(number, 3) округляет число number до трех десятичных знаков и возвращает результат.


Как вернуть двоичный код целого числа?

Чтобы получить двоичное представление целого числа в Python, можно использовать встроенную функцию bin():

number = 42
binary_representation = bin(number)
print(binary_representation)  # Вывод: '0b101010'

Функция bin() возвращает строку, начинающуюся с префикса '0b', за которым следует двоичное представление числа.


Приведите пример тернарного оператора

В Python тернарный оператор имеет следующий синтаксис:

x = <выражение1> if <условие> else <выражение2>

Пример использования тернарного оператора:

age = 25
status = "adult" if age >= 18 else "minor"
print(status)  # Вывод: "adult"

В этом примере, если переменная age больше или равна 18, то переменная status будет равна “adult”, в противном случае будет равна “minor”.

Собеседования: Аналитика данных

Смотри записи интервью, узнай, какие вопросы задают и как отвечают кандидаты.

Вопросы и ответы

Не нашли ответ? Напишите мне в чат. Я делаю Шпаргалку и сам отвечаю на сообщения. Расскажите, что не работает или чего вам не хватает. Может, смогу сразу взять это в работу.

Откуда взяты вопросы?

Из реальных собеседований. Основой подборки стал опыт Вадима Новосёлова: он проходил интервью и записывал вопросы. Подробнее о материалах.

Насколько эти вопросы актуальны?

Эти вопросы встречались нам на реальных собеседованиях в 2025 году. Мы регулярно проходим собеседования и пополняем подборку новыми вопросами. Основы профессии и ключевые технологии остаются востребованными годами, а детали конкретных инструментов и версий стоит сверять с текущей документацией.

На какой уровень рассчитана подборка?

Мы проходили собеседования на вакансии уровня Middle+, а иногда и на Senior-позиции. Вопросы из этих интервью вошли в подборку. Направления работы: Аналитик данных, BI-аналитик. Глубина обсуждения зависит от вакансии: будь готов объяснить основную идею, привести практический пример и разобрать ограничения и альтернативы решения.

Этот вопрос точно будет на моём собеседовании?

Гарантии нет: набор вопросов зависит от компании, задач команды, уровня вакансии и самого интервьюера. Эти вопросы уже встречались на реальных собеседованиях, но на твоём интервью ту же тему могут проверить другой формулировкой, практической задачей или обсуждением твоего опыта. Используй подборку, чтобы разобраться в теме: объясняй идею своими словами, приводи примеры и готовься обсудить ограничения и альтернативы решения. Так будет проще ответить и на знакомый вопрос, и на неожиданные уточнения.