IT-индустрия развивается как никогда быстро. На рынок постоянно выпускаются новые программные продукты, поэтому независимо от того, новичок вы в Python или уже опытный разработчик, вас всегда будет ждать множество возможностей.

Единственное условие — убедить будущего работодателя в вашей компетентности, показав свои умения на технических собеседованиях. Вам стоит хорошо к ним подготовиться, иначе работа достанется кому-то другому — порешайте задачи по Python, просмотрите популярные вопросы и ответы.

Я хочу поделиться с вами опытом прохождения собеседований по Python. Ниже представлен список вопросов, которые мне задавали, и возможные решения. Надеюсь, эта статья станет для вас руководством по получению работы Python-программиста.

1. В датасете Iris получите только те записи, где параметр Sepal.Length больше 6, а Sepal.Width больше 3,3

Датасет Iris можно:

Код

import pandas as pd

iris = pd.read_csv('iris.csv')

df = pd.DataFrame(iris) 

for i, j in df.iterrows():
    if (j['sepal_length'] > 6) & (j['sepal_width'] > 3.3):
        print(j)
        print()

Вывод

sepal_length          7.2
sepal_width           3.6
petal_length          6.1
petal_width           2.5
species         virginica
Name: 109, dtype: object

sepal_length          7.7
sepal_width           3.8
petal_length          6.7
petal_width           2.2
species         virginica
Name: 117, dtype: object

sepal_length          7.9
sepal_width           3.8
petal_length          6.4
petal_width             2
species         virginica
Name: 131, dtype: object

sepal_length          6.3
sepal_width           3.4
petal_length          5.6
petal_width           2.4
species         virginica
Name: 136, dtype: object

sepal_length          6.2
sepal_width           3.4
petal_length          5.4
petal_width           2.3
species         virginica
Name: 148, dtype: object

2. Как сложить соответствующие элементы двух списков?

Списки

a = [23,67,1]
b = [98,543,7]

Код

import numpy as np

a = np.array([23,67,1])
b = np.array([98,543,7])

c = np.sum((a,b), axis=0)

j = 0

for i in c:
    print("Index_" + str(j) + ":", i)
    j += 1

Вывод

Index_0: 121
Index_1: 610
Index_2: 8

3. Что такое *args и **kwargs? Приведите примеры применения

И то, и другое используется для передачи коллекции элементов в функцию. *args используется для передачи позиционных аргументов, а **kwargs — для ключевых аргументов (например, пары ключ-значение).

Пример использования ‘*args’

def myFun1(*argv):
    for a in argv:
        print(a)

myFun1(Добро пожаловать, 'на', 'AskMentor.io')

Вывод

Добро пожаловать
на
AskMentor.io

Пример использования ‘**kwargs’

def myFun2(**kwargs):
    for k, v in kwargs.items():
        print ("%s = %s" %(k, v))

myFun2(username = 'Андрей Борисов', email = 'example@domain.com', password = 'Abc123')

Вывод

username = Андрей Борисов
email = example@domain.com
password = Abc123

4. Как узнать, какие функции и переменные доступны в модуле?

Для получения списка переменных и функций, доступных в модуле, передайте имя модуля в функцию dir().

Пример

Допустим, у нас есть модуль под названием m.py с переменной и двумя определенными пользователем функциями.

name = "Андрей"
def myFun():
    return
def myFun2():
    return

Теперь отобразим переменные и имена функций m.py в другом модуле следующим образом:

import m
print(dir(m))

Вывод

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'myFun', 'myFun2', 'name']

Заметим, что функция dir() также выводит переменные и методы из стандартной библиотеки.

5. Что такое литералы в Python?

Литерал — значение, присвоенное переменной или константе. В Python четыре типа литералов:

  • числовые литералы;
  • строковые литералы;
  • boolean-литералы;
  • специальные литералы.

6. Как сложить два кортежа?

Конкатенация кортежей — объединение двух и более кортежей. Допустим, у нас есть два кортежа:

tuple_1 = (True,"Андрей",561)
tuple_2 = (47,100,False)

Сложим их с помощью символа ‘+’. Результатом выполнения следующей строки кода будет добавление элементов кортежа ‘tuple_2’ в конец ‘tuple_1’.

tuple_1 + tuple_2

Результат:

(True, 'Андрей', 561, 47, 100, False)

7. Что такое лямбда в Python?

Лямбда — маленькая функция в Python, которая выполняет только одно выражение, но добавлять можно произвольное количество параметров.

Обычно лямбда-функции используются внутри других функций.

Напишем лямбда-функцию, которая возвращает число, которое мы передаем в качестве аргумента, умноженное на 14.

x = lambda a: a * 14
print(x(3))

Вывод

42

8. Что такое срезы?

Срез — получение частей строки, массива, списка или кортежа. Мы передаем начальный и конечный индексы для указания позиций, между которыми находятся нужные данные. Важно отметить, что значение, находящееся по начальному индексу, добавляется в результат, а значение по конечному — нет.

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

В примере ниже срез выполнен с использованием квадратных скобок ‘[]’. Мы передали три аргумента и разделили их с помощью двоеточия ‘:’. Первый параметр — начальная позиция среза, второй — конечная, последний же определяет шаг.

countries = ("Россия", "США", "Германия", "Китай", "Франция", "Британия")
print(countries[0:5:2])

Вывод

('Россия', 'Германия', 'Франция')

Все три параметра среза опциональны — если не указать начальную позицию, Python примет ее за 0. Похожим образом, когда мы пропускаем второй параметр, используется длина массива, строки, кортежа или списка. Также по умолчанию Python принимает шаг, равный 1.

9. Что такое декораторы в Python?

Декораторы в Python — элемент для совершенствования функциональности существующих функций или классов. Предпочтительно использовать, когда разработчик хочет динамически обновлять работу функции без ее изменения.

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

Добавим подобную функциональность с помощью функции-декоратора.

def welcome_user(func):
    def inner(a, b):
        print("Добро пожаловать на AskMentor!")
        return func(a, b)
    return inner
@welcome_user

def author_name(first_name, last_name):
    print("Статью написала:", first_name, last_name)

author_name("Людмила", "Чеботарева")

Здесь вы видите, что welcome_user() — это декоратор, а author_name() — главная функция, которую мы обновили динамически.

Вывод

Добро пожаловать на AskMentor!
Статью написала: Людмила Чеботарева

10. Какой алгоритм используется в функциях sort() и sorted()?

Функции sort() и sorted() реализованы с использованием стабильного и эффективного алгоритма сортировки Timsort. В худшем случае O(n) будет равно O(N log N).

11. Как дебажить программу на Python?

В Python есть встроенный дебаггер pdb.

Начать дебаг python-файла можно c помощью подобной команды типа такой:

python -m pdb your-python-file.py

12. Что такое pickling и unpickling?

В Python есть популярная библиотека pickle, которая используется для сериализации объектов. Это когда Python получает на вход данные и конвертирует его их в поток байтов. Этот процесс трансформации объекта Python называется pickling.

Unpickling действие обратное — на вход принимается поток байт, который преобразуется в иерархию объектов.

13. Что такое представление списков? Приведите пример.

Представление списков — быстрый способ создать списки в Python. Вместо того, чтобы вручную прописывать значения для каждого индекса, можно просто заполнить список, «пройдясь» по данным.

Допустим, я хочу создать список из букв имени.

name_letters = [letter for letter in 'Борисов Андрей’]
print(name_letters)

Вывод

['Б', 'о', 'р', 'и', 'с', 'о', 'в', ' ', 'А', 'н ', 'д', 'р', 'е', 'й']

14. ‘(i for i in (54, 6, 71))’ — это кортежное включение?

Нет, в Python нет такого понятия, как кортежные включения.

15. Что такое monkey patching?

Monkey patching — динамическое изменение класса или модуля во время выполнения программы.

website_name.py

class Website_name:
    def func(self):
        print("Добро пожаловать на AskMentor.io!")

main.py

import website_name
def welcome(self):
    print("Добро пожаловать на AskMentor.io!")

# заменяем ссылку в поле "func" на "welcome"
website_name.Website_name.func = welcome
obj = website_name.Website_name()

# вызываем функцию "func()", ссылку в которой мы заменили функцией "welcome()"

obj.func()

Вывод

Добро пожаловать на AskMentor.io!

Вы заметили? Мы вызвали метод func(), а вывод получили от welcome()?

16. Что выведет код ниже? Объясните свой ответ.

Код

class Parent(object):
   x = 53
class Child_1(Parent):
   pass
class Child_2(Parent):
   pass
print(Parent.x, Child_1.x, Child_2.x)
Child_1.x = 12
print(Parent.x, Child_1.x, Child_2.x)
Parent.x = 89
print(Parent.x, Child_1.x, Child_2.x)

Вывод

53 53 53
53 12 53
89 12 89

Объяснение

Путаница возникает на последнем вызове print().

Перед вызовом print мы обновили значение x класса Parent, что автоматически обновляет значение Child_2.x, но не Child_1.x, поскольку мы уже установили его значение.

Другими словами, Python сначала использует поля/методы класса-ребенка и обращается к родительскому классу только если поля/метода нет в наследуемом классе.

17. Как можно отобразить предков узла бинарного дерева?

Допустим, у нас есть бинарное дерево. Получим предков узла 65 и отобразим их.

             58
           /    \
         42       3
       /    \
     0       65
   /
 17

Код

class Node: 
   # Создаем новый узел
   def __init__(self, data):
       self.data = data 
       self.left = None
       self.right = None
def displayAncestors(root, target):
   # Базовый случай
   if root == None:
       return False
    
   if root.data == target:
       return True

   # Вывести данный узел, если нужный нам узел находится в левом или правом поддереве
   if (displayAncestors(root.left, target) or
       displayAncestors(root.right, target)):
       print(root.data)
       return True
   # Иначе
   return False
# Тестируем функцию выше
root = Node(58)
root.left = Node(42)
root.right = Node(3)
root.left.left = Node(0)
root.left.right = Node(65)
root.left.left.left = Node(17)
displayAncestors(root, 65)

Вывод

42
58

Заключение

Практика перед собеседованием — важный момент для получения работы мечты. В этой статье мы затронули некоторые популярные вопросы, но знать вам нужно гораздо больше. Для подготовки к собеседованиям попрактикуйтесь на какой-нибудь из платформ, коих много.

Перевод статьи: 17 Python Interview Questions and Answers