Ответ 1
>>>> x = set([1, 2, 3])
>>>> y = x
>>>>
>>>> y |= set([4, 5, 6])
>>>> print x
set([1, 2, 3, 4, 5, 6])
>>>> print y
set([1, 2, 3, 4, 5, 6])
Заключение: наборы изменяемы.
Являются ли наборы Python изменчивыми?
Другими словами, если я это сделаю:
x = set([1, 2, 3])
y = x
y |= set([4, 5, 6])
Являются ли x
и y
все еще указывающими на один и тот же объект или это новый набор, созданный и назначенный y
?
>>>> x = set([1, 2, 3])
>>>> y = x
>>>>
>>>> y |= set([4, 5, 6])
>>>> print x
set([1, 2, 3, 4, 5, 6])
>>>> print y
set([1, 2, 3, 4, 5, 6])
Заключение: наборы изменяемы.
Ваши два вопроса разные.
Являются ли наборы Python изменчивыми?
Да: "mutable" означает, что вы можете изменить объект. Например, целые числа не изменяются: вы не можете изменить число 1
для обозначения чего-либо еще. Однако вы можете добавлять элементы в набор, который его мутирует.
Изменяется ли
y = x; y |= {1,2,3}
x
?
Да. Код y = x
означает "привязать имя y
к тому же самому объекту, который в настоящее время представляет имя x
". Код y |= {1,2,3}
вызывает магический метод y.__ior__({1,2,3})
под капотом, который мутирует объект, представленный именем y
. Поскольку это тот же объект, который представлен x
, вы должны ожидать, что набор изменится.
Вы можете проверить, указывает ли два имени точно одному и тому же объекту с помощью оператора is
: x is y
, только если объекты, представленные именами x
и y
, являются одним и тем же объектом.
Если вы хотите скопировать объект, обычный синтаксис y = x.copy()
или y = set(x)
. Однако это только мелкая копия: хотя он копирует заданный объект, члены указанного объекта не копируются. Если вам нужна глубокая копия, используйте copy.deepcopy(x)
.
Наборы Python делятся на два типа. Изменчивый и неизменный. Набор, созданный с помощью 'set', является изменяемым, а набор, созданный с помощью 'frozenset', является неизменным.
>>> s = set(list('hello'))
>>> type(s)
<class 'set'>
Следующие методы предназначены для изменчивых множеств.
s.add(item) - добавляет элемент в s. Не имеет никакого эффекта, если list
уже в s.
s.clear() - удаляет все элементы из s.
s.difference_update (t) - удаляет все элементы из s, которые также находятся в t.
s.discard(item) - удаляет элемент из s. Если элемент не является членом s, ничего не происходит.
Все эти операции изменяют наборы на месте. Параметр t может быть любым объектом, который поддерживает итерацию.
После изменения набора даже ссылки на их объекты совпадают. Я не знаю, почему в этом учебнике говорится, что множества неизменны.
>>> s1 ={1,2,3}
>>> id(s1)
140061513171016
>>> s1|={5,6,7}
>>> s1
{1, 2, 3, 5, 6, 7}
>>> id(s1)
140061513171016
print x,y
и вы увидите, что оба они указывают на один и тот же набор:
set([1, 2, 3, 4, 5, 6]) set([1, 2, 3, 4, 5, 6])
Наборы изменчивы
s = {2,3,4,5,6}
type(s)
<class 'set'>
s.add(9)
s
{2, 3, 4, 5, 6, 9}
Мы можем изменить элементы множества
Да, наборы Python являются изменяемыми, потому что мы можем добавлять, удалять элементы в набор, но наборы не могут содержать изменяемые элементы в себе. Как приведенный ниже код выдаст ошибку:
s = set([[1,2,3],[4,5,6]])
Таким образом, наборы являются изменяемыми, но не могут содержать изменяемые элементы, потому что набор внутренне использует хеш-таблицу для хранения своих элементов, поэтому для этого элементы набора должны быть хэшируемыми. Но изменяемые элементы, такие как список, не являются хэшируемыми.
Примечание:
Изменяемые элементы не являются хэшируемыми
Неизменяемые элементы могут быть хэшируемыми
Также как ключ словаря не может быть списком.
Я не думаю, что наборы Python изменяемы, как указано в книге " Learning Python 5th Edition от Mark Lutz - Oreilly Publications"