简体   繁体   English

Python 组是可变的吗?

[英]Are Python sets mutable?

Are sets in Python mutable? Python 中的集合是否可变?


In other words, if I do this:换句话说,如果我这样做:

x = set([1, 2, 3])
y = x

y |= set([4, 5, 6])

Are x and y still pointing to the same object, or was a new set created and assigned to y ? xy是否仍然指向相同的 object,或者是否创建了一个新集合并将其分配给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])
  • Sets are unordered.集合是无序的。
  • Set elements are unique.集合元素是唯一的。 Duplicate elements are not allowed.不允许重复元素。
  • A set itself may be modified, but the elements contained in the set must be of an immutable type.集合本身可以被修改,但集合中包含的元素必须是不可变类型。
set1 = {1,2,3}

set2 = {1,2,[1,2]}  --> unhashable type: 'list'
# Set elements should be immutable.

Conclusion: sets are mutable.结论:集合是可变的。

Your two questions are different.你的两个问题是不同的。

Are Python sets mutable? Python 集是可变的吗?

Yes: "mutable" means that you can change the object.是的:“可变”意味着您可以更改对象。 For example, integers are not mutable: you cannot change the number 1 to mean anything else.例如,整数是不可变的:您不能将数字1更改为其他任何含义。 You can, however, add elements to a set, which mutates it.但是,您可以将元素添加到集合中,从而对其进行变异。

Does y = x; y |= {1,2,3} y = x; y |= {1,2,3}y = x; y |= {1,2,3} y = x; y |= {1,2,3} change x ? y = x; y |= {1,2,3}改变x ?

Yes.是的。 The code y = x means "bind the name y to mean the same object that the name x currently represents".代码y = x表示“将名称y绑定到名称x当前表示的相同对象”。 The code y |= {1,2,3} calls the magic method y.__ior__({1,2,3}) under the hood, which mutates the object represented by the name y .代码y |= {1,2,3}y.__ior__({1,2,3})调用了魔法方法y.__ior__({1,2,3}) ,它改变了名称y表示的对象。 Since this is the same object as is represented by x , you should expect the set to change.由于这与x表示的对象相同,因此您应该期望集合会发生变化。


You can check whether two names point to precisely the same object using the is operator: x is y just if the objects represented by the names x and y are the same object.您可以使用is运算符检查两个名称是否完全指向同一个对象: x is y仅当名称xy表示的对象是同一个对象时。

If you want to copy an object, the usual syntax is y = x.copy() or y = set(x) .如果要复制对象,通常的语法是y = x.copy()y = set(x) This is only a shallow copy, however: although it copies the set object, the members of said object are not copied.然而,这只是一个拷贝:虽然它复制了集合对象,但并未复制所述对象的成员 If you want a deepcopy, use copy.deepcopy(x) .如果您想要copy.deepcopy(x) ,请使用copy.deepcopy(x)

Python sets are classified into two types. Python 集分为两种类型。 Mutable and immutable.可变的和不可变的。 A set created with 'set' is mutable while the one created with 'frozenset' is immutable.使用 'set' 创建的集合是可变的,而使用 'frozenset' 创建的集合是不可变的。

>>> s = set(list('hello'))
>>> type(s)
<class 'set'>

The following methods are for mutable sets.以下方法适用于可变集。

s.add(item) -- Adds item to s. s.add(item) -- 将项目添加到 s。 Has no effect if list is already in s.如果list已经在 s list则无效。

s.clear() -- Removes all items from s. s.clear() -- 从 s 中删除所有项目。

s.difference_update(t) -- Removes all the items from s that are also in t. s.difference_update(t) -- 从 s 中删除也在 t 中的所有项目。

s.discard(item) -- Removes item from s. s.discard(item) -- 从 s 中删除项目。 If item is not a member of s, nothing happens.如果 item 不是 s 的成员,则什么都不会发生。

All these operations modify the set s in place.所有这些操作都会在适当的位置修改 set 。 The parameter t can be any object that supports iteration.参数 t 可以是任何支持迭代的对象。

After changing the set, even their object references match.更改集合后,甚至它们的对象引用也匹配。 I don't know why that textbook says sets are immutable.我不知道为什么那本教科书说集合是不可变的。

    >>> 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])

Sets are muttable集合是可变的

s = {2,3,4,5,6}
type(s)
<class 'set'>
s.add(9)
s
{2, 3, 4, 5, 6, 9}

We are able to change elements of set我们能够改变集合的元素

Yes, Python sets are mutable because we can add, delete elements into set, but sets can't contain mutable items into itself.是的,Python 集合是可变的,因为我们可以在集合中添加、删除元素,但集合本身不能包含可变项。 Like the below code will give an error:像下面的代码会报错:

s = set([[1,2,3],[4,5,6]])

So sets are mutable but can't contain mutable items, because set internally uses hashtable to store its elements so for that set elements need to be hashable.所以集合是可变的,但不能包含可变项,因为集合内部使用哈希表来存储其元素,因此集合元素需要是可哈希的。 But mutable elements like list are not hashable.但是像 list 这样的可变元素是不可散列的。

Note:笔记:
Mutable elements are not hashable可变元素不可散列
Immutable elements are hashable不可变元素是可散列的

Just like key of a dictionary can't be a list.就像字典的键不能是列表一样。

Sets are mutable, you can add to them.集合是可变的,您可以添加它们。 The items they contain CAN BE MUTABLE THEY MUST BE HASHABLE.它们包含的项目可以是可变的,但它们必须是可清除的。 I didn't see any correct answers in this post so here is the code我在这篇文章中没有看到任何正确答案所以这是代码

class MyClass:
"""
    This class is hashable, however, the hashes are
    unique per instance not the data so a set will
    have no way to determine equality
"""
def __init__(self):
    self.my_attr = "no-unique-hash"
def __repr__(self):
    return self.my_attr

class MyHashableClass:
    """
        This object implements __hash__ and __eq__ and will
    produce the same hash if the data is the same. 
    That way a set can remove equal objects.
    """
    def __init__(self):
        self.my_attr = "unique-hash"
    def __hash__(self):
        return hash(str(self))
    def __eq__(self, other):
        return hash(self) == hash(other)
    def __repr__(self):
        return self.my_attr

myclass_instance1 = MyClass()
myclass_instance2 = MyClass()

my_hashable_instance1 = MyHashableClass()
my_hashable_instance2 = MyHashableClass()

my_set = {
    myclass_instance1,
    myclass_instance2,
    my_hashable_instance1,
    my_hashable_instance2, # will be removed, not unique
} # sets can contain mutuable types
# The only objects set can not contain are objects
# with the __hash__=None, such as List, Dict, and Sets

print(my_set)
# prints {unique-hash, no-unique-hash, no-unique-hash }

my_hashable_instance1.my_attr = "new-hash"  # mutating the object

# now that the hashes between the objects are differrent
# instance2 can be added
my_set.add(my_hashable_instance2) 

print(my_set)
# {new-hash, no-unique-hash, no-unique-hash, unique-hash}

I don't think Python sets are mutable as mentioned clearly in book " Learning Python 5th Edition by Mark Lutz - O'Reilly Publications "我不认为 Python 集是可变的,正如在“ Mark Lutz 的Learning Python 5th Edition - O'Reilly Publications 》”一书中明确提到的那样

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM