Как работает для списка [1:]?

Если мой код выглядит так:

l = [1, 2, 3, 4]

s = l[1:]

То s — это все еще ссылка на l, которая читает его по правилу [1:], или же создался новый список l = [2, 3, 4], значение которого присвоили s?


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

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

Проще всего это внести изменения и посмотреть, что происходит

l = [1, 2, 3, 4]
s = l[1:]

s.append(10)
print(l, s)
[1, 2, 3, 4] [2, 3, 4, 10]

то есть s не ссылается больше на l и изменения s не привносят изменения в l

Ну и что в говорит документация

list.copy()
Return a shallow copy of the list. Equivalent to a[:].

То есть, создается копия части родительского списка

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

это отдельный объект (срез)

вы можете проверить это следующим кодом

l = [1, 2, 3, 4]

s = l[1:]

l[1] = 7

print(l) # 1, 7, 3, 4
print(s) # 2, 3, 4 а не 7, 3, 4
→ Ссылка
Автор решения: MaxU

На самом деле это интересный и непростой вопрос. Когда вы создаете срез, Python создает копии ссылок на элементы списка:

In [58]: l = [1000, 2000, 3000, 4000]

In [59]: s = l[1:]

In [60]: [id(x) for x in l]
Out[60]: [140412420854224, 140412420857168, 140412420854032, 140412420857648]

In [61]: [id(x) for x in s]
Out[61]: [140412420857168, 140412420854032, 140412420857648]

с первого взгляда может показаться, что s - это ссылка на l[1:], но если изменить один из элементов в s - это не изменит данные в исходном l:

In [62]: s[0] += 111

In [63]: s
Out[63]: [2111, 3000, 4000]

In [64]: l
Out[64]: [1000, 2000, 3000, 4000]

если копнуть глубже и использовать список списков - ситуация кардинально изменится - обратите внимание на измененный элемент в исходном подсписке ll, после того как мы изменили элемент в подсписке ss:

In [65]: ll = [[1000, 1000], [2000, 2000]]

In [66]: ss = ll[1:]

In [67]: ss[0][0] += 111

In [68]: ll
Out[68]: [[1000, 1000], [2111, 2000]]

In [69]: ss
Out[69]: [[2111, 2000]]

но id все еще совпадают:

In [70]: [id(x) for x in ll]
Out[70]: [140411607786432, 140413521522240]

In [71]: [id(x) for x in ss]
Out[71]: [140413521522240]
→ Ссылка
Автор решения: GrAnd

Проще всего проверить, тот же это объект или нет - посмотреть его id.

l = [1, 2, 3, 4]
x = l
s = l[1:]

print("l id =", id(l))
print("x id =", id(x), "  x тот же что l :", id(x) == id(l))
print("s id =", id(s), "  s тот же что l :", id(s) == id(l))
l id = 139671557991232
x id = 139671557991232   x тот же что l : True
s id = 139671557937824   s тот же что l : False
→ Ссылка