В Python элементы списка меняют местами через множественное присваивание. Это коротко, читаемо и не требует временной переменной
Разберем обмен элементов списка: короткую запись через множественное присваивание, безопасную функцию с проверкой индексов и отличие изменения исходного списка от возврата новой копии
- Базовый пример
- Разбор по шагам
- Практические варианты
- Функция для обмена
- Обмен соседних элементов
- Частые ошибки
- Как проверить результат
- Проверка отрицательных индексов
- Безопасная функция обмена
- Когда это пригодится
- Практика на закрепление
- Практика: безопасный обмен с возвратом копии
- Когда менять исходный список, а когда копию
- Индексы перед обменом
- Итоговая практика: переставить задачу в очереди
Базовый пример
Базовый вариант:
items = ['a', 'b', 'c']
items[0], items[2] = items[2], items[0]
print(items)
Разбор по шагам
Запись items[a], items[b] = items[b], items[a] меняет два элемента местами без временной переменной. Python сначала вычисляет правую часть, а потом раскладывает значения обратно по индексам
Главный риск — неправильный индекс. Положительные индексы должны быть меньше длины списка, отрицательные можно разрешить, если вы сознательно поддерживаете поведение Python. В функции лучше явно решить, какие индексы допустимы, и вернуть понятный результат для ошибки
По этой теме полезно отдельно посмотреть Составьте еженедельное расписание занятий, чтобы расширить контекст и сравнить подходы
По этой теме полезно отдельно посмотреть Аннотации типов для декораторов в Python, чтобы расширить контекст и сравнить подходы
Практические варианты
Функция для обмена
def swap_items(items, first_index, second_index):
if first_index >= len(items) or second_index >= len(items):
return items
items[first_index], items[second_index] = items[second_index], items[first_index]
return items
print(swap_items(['a', 'b', 'c'], 0, 2))
Обмен соседних элементов
items = [1, 2, 3, 4]
index = 1
items[index], items[index + 1] = items[index + 1], items[index]
print(items)
Частые ошибки
Главная ошибка — не проверить индексы. Если индекс выходит за границы списка, Python выдаст IndexError. Для функции лучше заранее обработать такой случай
Как проверить результат
- запустить код на обычном примере
- проверить пустой список
- проверить список из одного элемента
- проверить повторы
- объяснить, меняется исходный список или создается новый
- вынести действие в функцию, если оно повторяется
Проверка отрицательных индексов
В Python отрицательные индексы работают с конца списка
items = ["a", "b", "c"]
items[0], items[-1] = items[-1], items[0]
print(items)
Это удобно, но может запутать новичка. Если пользователь вводит индекс сам, лучше явно проверить диапазон
Безопасная функция обмена
def swap_items(items, first_index, second_index):
if not 0 <= first_index < len(items):
return False
if not 0 <= second_index < len(items):
return False
items[first_index], items[second_index] = items[second_index], items[first_index]
return True
data = ["a", "b", "c"]
if swap_items(data, 0, 2):
print(data)
else:
print("Неверный индекс")
Когда это пригодится
Обмен элементов нужен в сортировках, перестановках, игровых задачах, очередях и интерфейсах, где пользователь меняет порядок элементов. Для простой перестановки не нужна временная переменная: множественное присваивание делает код короче и понятнее
Практика на закрепление
Практический сценарий — поднять задачу выше в списке
tasks = ["написать", "проверить", "опубликовать"]
index = 2
if index > 0:
tasks[index], tasks[index - 1] = tasks[index - 1], tasks[index]
print(tasks)
Такой прием используется в интерфейсах, очередях и учебных задачах на сортировку. Важно проверять границы: первый элемент нельзя поднять выше, а индекс за пределами списка приведет к ошибке
Функция для перемещения вверх:
def move_up(items, index):
if index <= 0 or index >= len(items):
return False
items[index], items[index - 1] = items[index - 1], items[index]
return True
tasks = ["a", "b", "c"]
move_up(tasks, 2)
print(tasks)
Проверьте индексы 0, 1 и длину списка. Так вы сразу увидите, где нужна защита от неверного действия
Практика: безопасный обмен с возвратом копии
Если не хотите менять исходный список, сначала сделайте копию. Затем проверьте индексы и поменяйте элементы местами уже в копии
def swap_copy(items, first_index, second_index):
if first_index < 0 or second_index < 0:
return items[:]
if first_index >= len(items) or second_index >= len(items):
return items[:]
result = items[:]
result[first_index], result[second_index] = result[second_index], result[first_index]
return result
items = ["a", "b", "c"]
print(swap_copy(items, 0, 2))
print(swap_copy(items, 0, 10))
print(items)
Проверьте три ситуации: обычный обмен, одинаковые индексы и индекс за пределами списка. После этого будет понятно, меняет ли функция исходные данные и что она делает при ошибке
Когда менять исходный список, а когда копию
Если список используется только внутри одной функции, менять его на месте нормально. Но если тот же список нужен дальше в исходном порядке, лучше вернуть копию с перестановкой. Так меньше неожиданных побочных эффектов
Простой ориентир такой: метод для внутренней обработки может менять список, а функция для повторного использования чаще должна возвращать новый результат. Поэтому в учебных задачах полезно написать оба варианта и сравнить поведение через print(items) после вызова функции
Еще одна проверка — одинаковые индексы. Если поменять элемент сам с собой, список не должен испортиться. Такой случай выглядит мелким, но он показывает, насколько спокойно функция ведет себя на границе условия
Индексы перед обменом
Перед обменом проверьте, что оба индекса относятся к существующим элементам. Для новичка проще сначала запретить отрицательные индексы, а уже потом отдельно изучить, как Python работает с -1
def is_valid_index(items, index):
return 0 <= index < len(items)
items = ["a", "b", "c"]
print(is_valid_index(items, 0))
print(is_valid_index(items, -1))
print(is_valid_index(items, 3))
После такой проверки обмен становится предсказуемым: если индекс неверный, функция ничего не меняет и не падает
Итоговая практика: переставить задачу в очереди
Сделайте функцию, которая меняет местами две задачи в очереди. Она должна вернуть новый список, чтобы исходная очередь осталась доступной для сравнения
def move_tasks(tasks, first_index, second_index):
if first_index < 0 or second_index < 0:
return tasks[:]
if first_index >= len(tasks) or second_index >= len(tasks):
return tasks[:]
result = tasks[:]
result[first_index], result[second_index] = result[second_index], result[first_index]
return result
tasks = ["план", "код", "проверка"]
print(move_tasks(tasks, 0, 2))
print(move_tasks(tasks, 0, 5))
print(tasks)
Если результат отличается от исходного списка только при корректных индексах, обмен элементов работает предсказуемо