Есть ли в Python оператор, который будет разрешаться как True, только если все элементы двух составных списков имеют разные идентификаторы

#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) не меняют свои идентификаторы. Меняются только изменяемые объекты списка.