Python: задачки и вопросы
7.52K 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
Код пытается изменить первый символ строки '𝙷𝚎𝚗𝚗𝚢' на '𝙿', но это приводит к ошибке 𝚃𝚢𝚙𝚎𝙴𝚛𝚛𝚘𝚛, поскольку строки в Python являются неизменяемыми (𝚒𝚖𝚖𝚞𝚝𝚊𝚋𝚕𝚎) объектами.

Из документации Python:
«Изменчивость объекта определяется его типом; например, числа, строки и кортежи являются неизменяемыми, а словари и списки — изменяемыми».

При попытке выполнить операцию присваивания 𝚗𝚊𝚖𝚎[𝟶] = '𝙿' интерпретатор выдаст ошибку:

`𝚃𝚢𝚙𝚎𝙴𝚛𝚛𝚘𝚛: '𝚜𝚝𝚛' 𝚘𝚋𝚓𝚎𝚌𝚝 𝚍𝚘𝚎𝚜 𝚗𝚘𝚝 𝚜𝚞𝚙𝚙𝚘𝚛𝚝 𝚒𝚝𝚎𝚖 𝚊𝚜𝚜𝚒𝚐𝚗𝚖𝚎𝚗𝚝`

Для изменения строки необходимо создать новую строку. Существует несколько способов:

🔘 Использование срезов: 𝚗𝚊𝚖𝚎 = '𝙿' + 𝚗𝚊𝚖𝚎[𝟷:]
🔘 Использование метода 𝚛𝚎𝚙𝚕𝚊𝚌𝚎(): 𝚗𝚊𝚖𝚎 = 𝚗𝚊𝚖𝚎.𝚛𝚎𝚙𝚕𝚊𝚌𝚎('𝙷', '𝙿', 𝟷)
🔘 Использование форматирования строк: 𝚗𝚊𝚖𝚎 = 𝚏'𝙿{𝚗𝚊𝚖𝚎[𝟷:]}'

В данном случае правильным решением было бы:
𝚗𝚊𝚖𝚎 = '𝙿' + 𝚗𝚊𝚖𝚎[𝟷:]
𝚙𝚛𝚒𝚗𝚝(𝚗𝚊𝚖𝚎) # Выведет: 𝙿𝚎𝚗𝚗𝚢

Фундаментальное свойство строк в Python — их неизменяемость, которая обеспечивает безопасность данных и оптимизацию памяти.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🧩 Что выведет код?
Anonymous Quiz
3%
abc
12%
wxyz
75%
xyz
10%
Error
1
При работе со срезами (𝚜𝚕𝚒𝚌𝚒𝚗𝚐) можно использовать отрицательные индексы. Отрицательный индекс означает позицию элемента, отсчитываемую с конца строки. Например, индекс −𝟷 соответствует последнему элементу, индекс −𝟸 — предпоследнему и так далее.

В данном случае, 𝚕𝚎𝚝𝚝𝚎𝚛𝚜 = '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝙸𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣' — строка длиной 𝟸𝟼 символов. 𝚕𝚎𝚝𝚝𝚎𝚛𝚜[−𝟹:] — срез с отрицательным индексом от −𝟹 до конца строки.

Отрицательный индекс −𝟹 означает третий символ с конца строки. Для строки '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝙸𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣' это символ '𝚡':
🔘 Позиция −𝟷: '𝚣' (последний)
🔘 Позиция −𝟸: '𝚢' (предпоследний)
🔘 Позиция −𝟹: '𝚡' (третий с конца)

Срез 𝚕𝚎𝚝𝚝𝚎𝚛𝚜[−𝟹:] берет все символы начиная с позиции −𝟹 (включительно) до конца строки, то есть последние три символа: '𝚡𝚢𝚣'.

Из
документации Python:
«Некоторые последовательности, включая встроенные, интерпретируют отрицательные индексы, добавляя длину последовательности. Например, `𝚊[−𝟸]` эквивалентно `𝚊[𝚗−𝟸]`, то есть обращается ко второму с конца элементу последовательности `𝚊` длиной `𝚗`. Замечание, сделанное выше об отрицательных индексах, также относится и к отрицательным границам срезов».

При использовании срезов с отрицательными индексами удобно извлекать элементы с конца последовательности, не зная точно её длину.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
В коде демонстрируется работа со встроенными функциями Python, которые используются как объекты первого класса.

Пошагово:

🔘 𝚏𝚞𝚗𝚌𝚜 = [𝚕𝚎𝚗, 𝚖𝚊𝚡, 𝚖𝚒𝚗] — создается список, содержащий три встроенные функции как объекты
🔘 𝚕𝚜𝚝 = [𝟷, 𝟸, 𝟹, 𝟺] — создается список чисел
🔘 В цикле 𝚏𝚘𝚛 𝚏𝚞𝚗𝚌 𝚒𝚗 𝚏𝚞𝚗𝚌𝚜 каждая функция вызывается с аргументом 𝚕𝚜𝚝:
− 𝚏𝚞𝚗𝚌(𝚕𝚜𝚝) для 𝚏𝚞𝚗𝚌 = 𝚕𝚎𝚗 возвращает 𝚕𝚎𝚗(𝚕𝚜𝚝) = 𝟺 (длина списка из 𝟺 элементов)
− 𝚏𝚞𝚗𝚌(𝚕𝚜𝚝) для 𝚏𝚞𝚗𝚌 = 𝚖𝚊𝚡 возвращает 𝚖𝚊𝚡(𝚕𝚜𝚝) = 𝟺 (максимальный элемент)
− 𝚏𝚞𝚗𝚌(𝚕𝚜𝚝) для 𝚏𝚞𝚗𝚌 = 𝚖𝚒𝚗 возвращает 𝚖𝚒𝚗(𝚕𝚜𝚝) = 𝟷 (минимальный элемент)

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

Из документации Python:

Функция 𝚕𝚎𝚗():
«Возвращает число элементов в объекте. Аргументом может быть последовательность (например, строка, байты, кортеж, список или диапазон) или коллекция (например, словарь, множество или замороженное множество)».

Функция 𝚖𝚊𝚡():
«Возвращает наибольший элемент в итерируемом объекте или наибольший из двух и более аргументов».

Функция 𝚖𝚒𝚗():
«Возвращает наименьший элемент в итерируемом объекте или наименьший из двух и более аргументов».

Таким образом, код выполняется без ошибок и выводит на экран по одному значению на каждой итерации цикла:
🔘 В первой итерации: 𝚕𝚎𝚗(𝚕𝚜𝚝) = 𝟺
🔘 Во второй итерации: 𝚖𝚊𝚡(𝚕𝚜𝚝) = 𝟺
🔘 В третьей итерации: 𝚖𝚒𝚗(𝚕𝚜𝚝) = 𝟷
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🧩 Что выведет код?
Anonymous Quiz
19%
hIjklmnopqrstuvwxyz
15%
abcdefghIjklmnopqrs
61%
ahov
5%
Error
1
Строка 𝚕𝚎𝚝𝚝𝚎𝚛𝚜 = '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝙸𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣' содержит 𝟸𝟼 символов. При использовании 𝚕𝚎𝚝𝚝𝚎𝚛𝚜[::𝟽] применяется синтаксис среза с тремя параметрами, разделенными двоеточиями.

Пошагово:
🔘 𝚕𝚎𝚝𝚝𝚎𝚛𝚜[::𝟽] означает срез строки с параметрами [𝚜𝚝𝚊𝚛𝚝:𝚜𝚝𝚘𝚙:𝚜𝚝𝚎𝚙]
🔘 Первый параметр (𝚜𝚝𝚊𝚛𝚝) не указан, поэтому 𝚜𝚝𝚊𝚛𝚝 = 𝟶 (начало строки)
🔘 Второй параметр (𝚜𝚝𝚘𝚙) не указан, поэтому 𝚜𝚝𝚘𝚙 = конец строки
🔘 Третий параметр (𝚜𝚝𝚎𝚙) = 𝟽, что означает извлечение каждого 𝟽−го символа

Таким образом, извлекаются символы на позициях:
🔘 Индекс 𝟶: '𝚊'
🔘 Индекс 𝟽: '𝚑'
🔘 Индекс 𝟷𝟺: '𝚘'
🔘 Индекс 𝟸𝟷: '𝚟'
🔘 Индекс 𝟸𝟾: выходит за пределы строки (строка имеет индексы 𝟶−𝟸𝟻)

Результат: '𝚊𝚑𝚘𝚟'

𝙲интаксис среза определяется следующим образом:

𝚙𝚛𝚘𝚙𝚎𝚛_𝚜𝚕𝚒𝚌𝚎 ::= [𝚕𝚘𝚠𝚎𝚛_𝚋𝚘𝚞𝚗𝚍] ":" [𝚞𝚙𝚙𝚎𝚛_𝚋𝚘𝚞𝚗𝚍] [ ":" [𝚜𝚝𝚛𝚒𝚍𝚎] ]

Параметр 𝚜𝚝𝚛𝚒𝚍𝚎 определяет шаг, с которым выбираются элементы последовательности. Если 𝚜𝚝𝚛𝚒𝚍𝚎 положителен, элементы выбираются слева направо; если 𝚜𝚝𝚛𝚒𝚍𝚎 больше 𝟷, между выбираемыми элементами будут пропущены (𝚜𝚝𝚛𝚒𝚍𝚎 − 𝟷) элементов.

Если присутствует 𝚜𝚝𝚛𝚒𝚍𝚎, то первая индексная граница по умолчанию равна 𝙽𝚘𝚗𝚎, иначе 𝟶. Вторая индексная граница по умолчанию равна 𝙽𝚘𝚗𝚎. Если 𝚜𝚝𝚛𝚒𝚍𝚎 отрицателен, первая индексная граница по умолчанию равна 𝙽𝚘𝚗𝚎, иначе 𝚕𝚎𝚗(𝚜) − 𝟷, а вторая индексная граница по умолчанию равна −(𝚕𝚎𝚗(𝚜) + 𝟷).»

В данном случае с положительным шагом 𝟽 и отсутствием явных границ 𝚜𝚝𝚊𝚛𝚝 и 𝚜𝚝𝚘𝚙, по умолчанию используются значения 𝟶 и 𝚕𝚎𝚗(𝚕𝚎𝚝𝚝𝚎𝚛𝚜) соответственно, что приводит к выбору каждого 𝟽−го символа начиная с позиции 𝟶.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Короче, в ШОРТКАТ ищут менторов — Senior Python-разработчиков

ШОРТКАТ — менторская платформа от команды разработчиков из бигтеха. Ребята помогают найти крутую работу, апнуть грейд или сменить стек.

Что надо будет делать: проводить тестовые собесы → оценивать грейд → помогать разбираться в сложных темах.

Что взамен:
От 40К за 5-7 часов работы в неделю
Доступ к обучению и комьюнити сильных менторов из Яндекс, Uber, VK, Сбер
Возможность выступать на эфирах, куда уже приходят 500+ джавистов, и стать заметнее на рынке

Заполняй форму — с тобой свяжутся и расскажут все подробности

Это #партнёрский пост
😁1
Из документации Python:

𝚜𝚝𝚛.𝚜𝚙𝚕𝚒𝚝(𝚜𝚎𝚙=𝙽𝚘𝚗𝚎, 𝚖𝚊𝚡𝚜𝚙𝚕𝚒𝚝=−𝟷)
«Возвращает список слов в строке, используя 𝚜𝚎𝚙 как разделитель строк. Если 𝚜𝚎𝚙 не указан или равен 𝙽𝚘𝚗𝚎, разделителем считается любая последовательность пробельных символов. Если разделителем является пробельный символ или 𝚜𝚎𝚙 равен 𝙽𝚘𝚗𝚎, результат не содержит пустых строк».

Строка 𝚝𝚊𝚜𝚔𝚜 содержит символы перевода строки между задачами: «𝚐𝚎𝚝_𝚐𝚕𝚘𝚟𝚎𝚜», «𝚐𝚎𝚝_𝚖𝚊𝚜𝚔», «𝚐𝚒𝚟𝚎_𝚌𝚊𝚝_𝚟𝚒𝚝𝚊𝚖𝚒𝚗𝚜». Вызов 𝚝𝚊𝚜𝚔𝚜.𝚜𝚙𝚕𝚒𝚝() использует поведение 𝚜𝚙𝚕𝚒𝚝 по умолчанию: разделение по последовательностям пробельных символов (включая перевод строки) с игнорированием пустых фрагментов.

Пошагово:
🔘 Исходная строка: '𝚐𝚎𝚝_𝚐𝚕𝚘𝚟𝚎𝚜\𝚗\𝚗𝚐𝚎𝚝_𝚖𝚊𝚜𝚔\𝚗\𝚗𝚐𝚒𝚟𝚎_𝚌𝚊𝚝_𝚟𝚒𝚝𝚊𝚖𝚒𝚗𝚜'
🔘 По умолчанию 𝚜𝚎𝚙 = 𝙽𝚘𝚗𝚎, поэтому разделителями считаются любые пробельные символы (пробел, табуляция, перевод строки и т.д.), а последовательности из нескольких пробельных символов считаются одним разделителем
🔘 Пустые элементы между двумя переводами строки не попадают в результат
🔘 Результат: ['𝚐𝚎𝚝_𝚐𝚕𝚘𝚟𝚎𝚜', '𝚐𝚎𝚝_𝚖𝚊𝚜𝚔', '𝚐𝚒𝚟𝚎_𝚌𝚊𝚝_𝚟𝚒𝚝𝚊𝚖𝚒𝚗𝚜']
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Метод 𝚛𝚎𝚙𝚕𝚊𝚌𝚎() возвращает новую строку и не изменяет исходную. Результат вызова метода не сохраняется в переменную, поэтому переменная 𝚜𝚎𝚝𝚞𝚙 остается неизменной.

Пошагово:
🔘 Переменной 𝚜𝚎𝚝𝚞𝚙 присваивается строка «Утка входит в бар...»
🔘 Вызывается метод 𝚜𝚎𝚝𝚞𝚙.𝚛𝚎𝚙𝚕𝚊𝚌𝚎('Утка', 'Сурок'), который создает и возвращает новую строку «Сурок входит в бар...»
🔘 Результат метода не присваивается обратно в переменную 𝚜𝚎𝚝𝚞𝚙
🔘 При выводе 𝚙𝚛𝚒𝚗𝚝(𝚜𝚎𝚝𝚞𝚙) выводится исходная строка, которая не изменилась

Из документации Python:

𝚜𝚝𝚛.𝚛𝚎𝚙𝚕𝚊𝚌𝚎(𝚘𝚕𝚍, 𝚗𝚎𝚠[, 𝚌𝚘𝚞𝚗𝚝])
«Возвращает копию строки со всеми вхождениями подстроки 𝚘𝚕𝚍, замененными на 𝚗𝚎𝚠. Если указан необязательный аргумент 𝚌𝚘𝚞𝚗𝚝, заменяются только первые 𝚌𝚘𝚞𝚗𝚝 вхождений».

Метод возвращает новую строку, а не изменяет существующую, поскольку строки в Python являются неизменяемыми (𝚒𝚖𝚖𝚞𝚝𝚊𝚋𝚕𝚎) объектами. Для сохранения результата замены необходимо присвоить возвращаемое значение переменной:

𝚜𝚎𝚝𝚞𝚙 = 𝚜𝚎𝚝𝚞𝚙.𝚛𝚎𝚙𝚕𝚊𝚌𝚎('Утка', 'Сурок')
𝚙𝚛𝚒𝚗𝚝(𝚜𝚎𝚝𝚞𝚙) # Сурок входит в бар...
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🕊1
Метод умножения списка создаёт несколько ссылок на один и тот же внутренний список, а не независимые копии, поэтому все строки в 𝚖𝚊𝚝𝚛𝚒𝚡 указывают на один объект. Изменение элемента 𝚖𝚊𝚝𝚛𝚒𝚡 фактически меняет общий вложенный список, и та же единица появляется в каждой строке. Проверить это можно по 𝚒𝚍: [𝚒𝚍(𝚛𝚘𝚠) 𝚏𝚘𝚛 𝚛𝚘𝚠 𝚒𝚗 𝚖𝚊𝚝𝚛𝚒𝚡] даёт одинаковые значения.

Как правильно: создавать каждую строку заново, например с генератором списков:

𝚖𝚊𝚝𝚛𝚒𝚡 = [[𝟶 𝚏𝚘𝚛 _ 𝚒𝚗 𝚛𝚊𝚗𝚐𝚎(𝟹)] 𝚏𝚘𝚛 _ 𝚒𝚗 𝚛𝚊𝚗𝚐𝚎(𝟹)]

Теперь каждая строка независима, и изменение одной не затрагивает остальные.

Для копирования уже созданной матрицы используйте копирование по элементам, например 𝚕𝚒𝚜𝚝(𝚖𝚊𝚙(𝚕𝚒𝚜𝚝, 𝚖𝚊𝚝𝚛𝚒𝚡)) или 𝚍𝚎𝚎𝚙𝚌𝚘𝚙𝚢 из модуля 𝚌𝚘𝚙𝚢, если внутри есть вложенные структуры.
👍21