Python никогда не копирует, если вы специально не попросите его сделать копию. Это совершенно простое, понятное и полностью понятное правило. Наложение на него исключений и различий, таких как «за исключением следующих обстоятельств в пределах понимания списка ...», было бы полной глупостью: если бы дизайн Python когда-либо находился под управлением кого-то с такими сумасшедшими идеями, Python был бы больным искаженный, полуразбитый язык не стоит изучать. Спасибо за то, что снова осчастливили меня осознанием того, что это не случай!
Вы хотите копию? Сделайте копию! Это всегда решение в Python, когда вы предпочитаете накладные расходы на копию, потому что вам нужно внести некоторые изменения, которые не должны отражаться в оригинале. То есть при чистом подходе вы бы сделали
dcopy = list(d)
[dcopy.pop() for _ in range(len(d))]
Если вы очень заинтересованы в том, чтобы все было в одном выражении, вы можете, хотя это, возможно, не код, который можно было бы назвать «чистым»:
[dcopy.pop() for dcopy in [list(d)] for _ in range(len(d))]
т. Е. Обычный трюк, который используется, когда действительно хочется сложить присвоение в понимание списка (добавьте предложение for
, где «управляющая переменная» - это имя, которое вы хотите назначить, и «цикл» "находится над последовательностью из одного элемента значения, которое вы хотите присвоить).
Функциональные языки никогда не изменяют данные, поэтому они также не копируют (и не обязаны). Python не является функциональным языком, но, конечно, есть много вещей, которые вы можете делать в Python "функциональным способом", и часто это лучший способ. Например, намного лучшая замена для вашего понимания списка (гарантированно будет иметь идентичные результаты и не повлияет на d
, а значительно быстрее, более кратко и чище):
d[::-1]
(АКА "Марсианский смайлик", по моей жене Анне ;-). Срез (не срез присваивание , что является другой операцией) всегда выполняет копирование в ядре Python (язык и стандартная библиотека), хотя, конечно, не обязательно в независимо разработанных сторонних модулях, таких как популярный numpy
( который предпочитает видеть срез как «вид» на оригинале numpy.array
).