Задачи на работу с типами в Python
Практические задачи по типам данных Python
Вопрос: Как проверить тип переменной и убедиться, что это список, а не строка?
Основной способ: использование isinstance()
Функция isinstance позволяет проверить принадлежность объекта к указанному типу или кортежу типов. Это предпочтительнее, чем сравнение с type(), так как учитывает наследование.
value = [1, 2, 3]
if isinstance(value, list):
print('Это список')
else:
print('Не список')Python типы данных задачи (задачи на типы данных в python)
Это список
реализация алгоритмов на python (реализация алгоритмов)
Такой подход гибок: можно проверить сразу несколько типов: isinstance(value, (list, tuple)).
Вариант: использование type() для точного сравнения
Если нужно строгое совпадение типа (без учёта подклассов), применяется type(value) is list или type(value) == list.
value = [1, 2, 3]
if type(value) is list:
print('Точный тип list')
повторить цикл python (повторение цикла)
Однако для bool это может дать неожиданный результат: type(True) is int вернёт False, хотя isinstance(True, int) вернёт True.
Типичная ошибка: путаница между type() и isinstance()
Начинающие часто пишут if type(x) == 'list' или сравнивают со строкой. Это неверно. Также забывают, что bool является подклассом int. Использование type(x) is int не обнаружит True как целое число.
Вопрос: Как преобразовать строку в целое число без риска ошибки, если строка содержит нецифровые символы?
Основной способ: try-except
s = '123'
try:
num = int(s)
print(f'Число: {num}')
except ValueError:
print('Не удалось преобразовать')приведи пример на python (пример на python)
Число: 123
Это надёжный метод, перехватывающий ValueError. Подходит для любых входных данных.
Вариант: предварительная проверка .isdigit()
Метод str.isdigit() возвращает True, если все символы в строке являются цифрами. Однако он не обрабатывает отрицательные числа и числа с плавающей точкой.
s = '123'
if s.isdigit():
num = int(s)
else:
print('Некорректная строка')
Недостаток: не работает для '-123' или '12.3'.
Ошибка: потеря исключений при использовании isdigit()
Многие считают, что проверка isdigit() полностью гарантирует успешное преобразование, но это не так: строка '١٢٣' (арабские цифры) вернёт True, но int('١٢٣') вызовет ValueError. Поэтому try-except остаётся более универсальным.
Вопрос: Как создать независимую копию списка, чтобы изменения не затрагивали оригинал?
Основной способ: shallow copy через list() или срез [:]
original = [1, 2, [3, 4]]
copy_list = list(original)
copy_list[0] = 100
print(original) # [1, 2, [3, 4]]
print(copy_list) # [100, 2, [3, 4]]
[1, 2, [3, 4]] [100, 2, [3, 4]]
Однако для вложенных объектов (список внутри списка) изменения всё равно отразятся, так как копируется ссылка. Для полной независимости нужна глубокая копия.
Вариант: deep copy из модуля copy
import copy
original = [1, 2, [3, 4]]
deep_copy = copy.deepcopy(original)
deep_copy[2][0] = 999
print(original) # [1, 2, [3, 4]]
print(deep_copy) # [1, 2, [999, 4]]
Глубокая копия рекурсивно копирует все вложенные объекты.
Ошибка: забвение о поверхностном копировании для вложенных структур
При использовании list() или [:] внутренние изменяемые объекты остаются общими. Это может приводить к трудноуловимым багам, когда одна часть кода меняет вложенный список, а другая ожидает его неизменности.
Дополнительные расширенные примеры
Проверка типа с помощью абстрактных базовых классов
Использование collections.abc позволяет проверять, является ли объект итерируемым, последовательностью и т.д.
from collections.abc import Iterable, Sequence, MutableSequence
print(isinstance([1,2], Iterable)) # True
print(isinstance((1,), Sequence)) # True
print(isinstance('abc', MutableSequence)) # False (строки не изменяемы)
True True False
Преобразование с использованием Decimal для точности
Тип Decimal из модуля decimal полезен для финансовых расчётов, где важна точность.
from decimal import Decimal
s = '123.456'
num = Decimal(s)
print(num * 2) # 246.912
246.912
Изменяемость кортежа с вложенным списком
Кортеж неизменяем, но если он содержит изменяемые объекты, их можно изменить.
t = (1, [2, 3])
t[1].append(4)
print(t) # (1, [2, 3, 4])
(1, [2, 3, 4])
Это демонстрирует, что неизменяемость кортежа не гарантирует неизменность содержимого.
Нехэшируемые типы в качестве ключей словаря
Ключами словаря могут быть только хэшируемые неизменяемые типы. Список не подходит.
d = {[1,2]: 'value'} # TypeError: unhashable type: 'list'
TypeError: unhashable type: 'list'
Использование кортежа вместо списка решает проблему.
Сравнение type() и isinstance() для пользовательских классов
class Animal: pass
class Dog(Animal): pass
dog = Dog()
print(type(dog) is Animal) # False
print(isinstance(dog, Animal)) # True
False True
isinstance учитывает иерархию наследования.