Автор оригинала: Robin Andrews.
Удивительная особенность списков Python
Что вы ожидаете, что вывод следующего кода Python?
def mutate_or_not(a_list):
a_list[0] = "I've changed"
my_list = [1, 2, 3]
mutate_or_not(my_list)
print(my_list)
[«Я изменил», 2, 3]
В зависимости от того, насколько хорошо вы понимаете, как Python Работает под капотом, вы можете быть удивлены этим результатом. Вы можете причинить это, так как my_list определяется в Глобальный объем он не имеет никакого бизнеса, когда его стоимость передается в mutate_or_not () в качестве недвижимости. Давайте рассмотрим, что здесь происходит.
Вы можете пройти через код с отличным инструментом онлайн визуализации здесь.
Обратите внимание, как список указан как my_list Переменная в глобальном кадре и той a_list Параметр внутри mutate_or_not () Отказ
Сравните ситуацию выше следующего:
def mutate_or_not(an_int):
an_int = 7
my_int = 5
mutate_or_not(my_int)
print(my_int)
>>> 5
Посмотрите на изображение ниже:
Трассировка кода доступна здесь. Можете ли вы увидеть, как нет ссылки между my_int (в глобальном кадре), а an_int , функциональный параметр?
Практический пример мутации списка Python
Предположим, вы хотите повернуть элементы в списке. После некоторого мышления вы можете придумать, как это так:
def rotate_list(lst, n):
n = n % len(lst)
lst = lst[-n:] + lst[:-n]
s1 = [1, 2, 5, 4]
rotate_list(s1, 1)
print(s1)
Вы можете ожидать, что вывод будет успешно повернутым списком: [4, 1, 2, 5] Отказ Однако это не работает!
Но разве ты не говорил, что списки были измельчены?
Выпуск вот что когда мы переназнаем lst Внутри функции исходное задание теряется, а lst Теперь просто ссылки на локальный параметр lst с новыми значениями. Оригинал lst Определен вне функции, остается неизменным.
Так что мы можем сделать с этим? Ну, одно решение приведено ниже, но это очень неуклюже и не практично. Это проиллюстрирует проблему, хотя, так что стоит смотреть на:
def rotate_list_2(lst):
lst[0], lst[1], lst[2], lst[3] = lst[3], lst[0], lst[1], lst[2]
s1 = [1, 2, 5, 4]
rotate_list_2(s1)
print(s1)
>>> [4, 1, 2, 5]
Причина, по которой это работает, что мы не переопределяем lst внутри функции. Вместо этого мы Мутате его элементы.
Однако намного лучшее решение использовать Список питона нарезки Как обсуждалось, например здесь Отказ В Python, my_list [:] относится к всему списку. Используя этот факт, мы можем переписать наши Rotate_List () Функция и используйте неизменность списков Python для достижения желаемого результата:
def rotate_list(lst, n):
n = n % len(lst)
lst[:] = lst[-n:] + lst[:-n]
s1 = [1, 2, 5, 4]
rotate_list(s1, 1)
print(s1)
Музные и неизменные типы данных в Python
Муравьеспособность в Python не просто применяется к спискам и целым числам, но и другие типы данных. Мы только что сосредоточились на списках в этой статье, чтобы сохранить вещи программными. Ниже приведена таблица для легкой ссылки.
| ✓ | список | |
| ✓ | Словарь | |
| ✓ | набор | |
| ✓ | Определенные пользователем классы | |
| ✓ | int. | |
| ✓ | плавать | |
| ✓ | десятичный | |
| ✓ | бол | |
| ✓ | нить | |
| ✓ | корпус | |
| ✓ | диапазон |
Заключение
Эта статья была о мультипликации списков в программировании Python. Знание того, как эти работы помогут вам избежать некоторых потенциально запутанных и трудоемких ошибок в вашем коде.
Счастливое кодирование!