#python #list
#python #Список
Вопрос:
Недавно я узнал, что некоторые назначения, например,
list2 = list1*1
list2 = list1[:]
list2 = copy.copy(list1) (need to import copy)
при использовании в составных списках (например, списках списков) создается list2, который имеет идентификатор, отличный от list1, но с компонентами, имеющими одинаковые идентификаторы. Таким образом, последующее изменение компонента list2 также изменит соответствующий компонент list1. list2 is list1
Оператор будет определять, False
имеют ли некоторые компоненты списков одинаковый идентификатор.
Мой вопрос:
есть ли что-то вроде notTheSame
команды, которая разрешает True
, только если list1 и list2, а также все их компоненты имеют разные идентификаторы?
Ответ №1:
Для выполнения проверки вручную можно записать простую функцию:
def all_unique(list1, list2):
return id(list1) != id(list2) and all(id(x) != id(y) for x, y in zip(list1, list2))
Для этой явной цели я не знаю встроенного средства.
Хотя это кажется странным требованием. Просто чтобы прояснить «определенные назначения», возвращающие элементы с одинаковыми идентификаторами: все методы, которые вы показываете (умножение последовательности, нарезка и copy.copy
), создают мелкие копии. Все, что они делают, это копируют внешнюю структуру, копируя ссылки на базовые объекты в новую структуру. Если вы хотите убедиться, что все объекты в копии уникальны (или, по крайней мере, уникальны в тех случаях, которые имеют значение), используйте copy.deepcopy
вместо этого. Он будет рекурсивно проходить через вспомогательные структуры и копировать все объекты.
Комментарии:
1. Спасибо, это отвечает на мой вопрос. Я относительный новичок и не был знаком с
all
командой
Ответ №2:
Нет, вам нужно будет написать функцию для сравнения всех элементов по их идентификаторам, но обратите внимание, что это имеет значение только в том случае, если они «не совпадают», если элементы изменяемы, и у них нет функции «ismutable ()».
Если вы хотите, чтобы копии вашего списка также копировали вложенные списки и другие изменяемые элементы, используйте:
import copy
list1 = copy.deepcopy(list2)
Обратите внимание, что ваша гипотетическая notTheSame
функция не будет работать даже с deepcopy, потому что неизменяемые элементы не должны иметь уникальных идентификаторов. Python может свободно оптимизировать неизменяемые элементы путем повторного использования объекта, поскольку его нельзя изменить.
Вот пример:
import copy
list1 = [1,2,[3,4,5],6,7,[8,9,10]]
list2 = list1.copy()
list3 = copy.deepcopy(list1)
def ids(x):
return ' '.join([f'{id(i):08x}' for i in x])
print(ids(list1))
print(ids(list2))
print(ids(list3))
Вывод:
7ffdff4006a0 7ffdff4006c0 22da8898200 7ffdff400740 7ffdff400760 22da8898a00
7ffdff4006a0 7ffdff4006c0 22da8898200 7ffdff400740 7ffdff400760 22da8898a00
7ffdff4006a0 7ffdff4006c0 22da88aea80 7ffdff400740 7ffdff400760 22da88ae980
Обратите внимание, что мелкая копия (2-я строка) Идентификаторы все одинаковые. Только 3-й и 6-й элементы имеют новый идентификатор в list3
(3-я строка). Целочисленные объекты (в любом случае, в реализации CPython) не меняют свои идентификаторы. Меняются только изменяемые объекты списка.