Копируются списки

Учусь питону. У решаю задачи. При их решении у меня уже 2 раз проблема что я изменяю один список а меняются все. Я новичок поэтому прошу немного разжевать для меня проблему.

Примеры кодов:

spisok1 = list()
spisok2 = list()
for _ in range(int(input())):
    spisok1.append(input())
spisok2 = spisok1
for _ in range(int(input())):
    for i in range(int(input())):
        spisok2[i] = spisok1[int(input()) - 1]
    spisok1 = spisok2[:i + 1]
for i in spisok1:
    print(i)

Суть этой задачи в том что в ней под наперстки можно класть предметы и тасовать, то есть:

  1. Ввод количества предметов и они кладутся под наперстки в том порядке как их записали. 1 наперсток - 1 предмет.
  2. сколько раз меняли наперстки
  3. В зависимости от пункта 2 столько то раз мы вводим: кол-во наперстков (можно меньше написать тогда остальные удалятся) и их порядок относительно прошлого например были 1 2 3 а мы можешь написать 3 2 1

если надо скину второй код с такой же ошибкой


Ответы (4 шт):

Автор решения: gil9red

spisok2 = spisok1 это не приведет к копированию списка, просто переменная spisok2 будет ссылаться на тот же объект, что spisok1. Поэтому меняя объект в spisok1 поменяется и для spisok2.

Для копии списка сделайте так:

spisok2 = list(spisok1) 
→ Ссылка
Автор решения: CrazyElf

На мой взгляд, копию списка лучше делать в явном виде:

spisok2 = spisok1.copy() 

Такой код ведь сразу понятно, что делает, в отличие от других вариантов копирования списка, которых много на самом деле - и list(spisok1), и spisok1[:], но в них не так очевидно на первый взгляд, что в коде происходит.

→ Ссылка
Автор решения: vadim vaduxa

Не стоит забывать что есть два способа копирования: поверхностный(описан в других ответах) и глубокое копирование copy.deepcopy - deepcopy не только создает копию объекта, но и рекурсивно создает копии входящих в него объектов.

Так, например в примере ниже видно, что при поверхностных копиях, изменения через spisok2 отражаются и в spisok1, чего не будет в copy.deepcopy

dct = {2: 3}
spisok1 = [1, dct]
print(spisok1)  # [1, {2: 3}]

# list
spisok2 = list(spisok1)
spisok2[1][2] = 4
print(spisok1)  # [1, {2: 4}] - список изменился

# copy
spisok2 = spisok1.copy()
spisok2[1][2] = 5
print(spisok1)  # [1, {2: 5}] - список изменился

# срез
spisok2 = spisok1[:]
spisok2[1][2] = 6
print(spisok1)  # [1, {2: 6}] - список изменился

# copy.deepcopy
import copy
spisok2 = copy.deepcopy(spisok1)
spisok2[1][2] = 7
print(spisok1)  # [1, {2: 6}] - список Не изменился
→ Ссылка
Автор решения: Vitek_228_69

Также можно использовать оператор среза

list1 = list2[:]
→ Ссылка