【问题标题】:Are Python sets mutable?Python 集合是可变的吗?
【发布时间】:2013-01-07 09:51:39
【问题描述】:

Python 中的集合是可变的吗?


换句话说,如果我这样做:

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

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

xy 是否仍指向同一个对象,或者是否已创建新集合并分配给 y

【问题讨论】:

  • 检测比询问更容易...print x is y 也适用于此。
  • Erm...所有这些反对票是因为问题是关于易于检查的东西吗?因为我目前无法使用 Python 解释器,而且我在网上找不到答案,所以这是一个拒绝投票的愚蠢理由。
  • 如果您可以访问互联网,您怎么不能使用翻译?浏览器内有 许多 个解释器,快速的 Google 搜索会显示给您。
  • 另外,通过查看the docs,您应该能够立即看到集合是可变的。
  • 我对这个问题 +1。措辞可能与作者所想的不一样。 (“Python 中的集合真的是可变的吗?”这个问题会更容易接受吗?)。而且,几乎所有内容都可以在文档中找到。这样,任何可以通过研究文档来解释的问题都是不合法的。我不认为有“愚蠢的问题”。每个人都处于不同的水平。有些初学者可能 70 岁,有些专家可能 12 岁。有不同的获取知识的方式。

标签: python set


【解决方案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])
  • 集合是无序的。
  • 集合元素是唯一的。不允许重复元素。
  • 可以修改集合本身,但集合中包含的元素必须是不可变类型。
set1 = {1,2,3}

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

结论:集合是可变的。

【讨论】:

【解决方案2】:

你的两个问题是不同的。

Python 集合是可变的吗?

是的:“可变”意味着您可以更改对象。例如,整数是不可变的:您不能将数字 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,前提是名称 xy 表示的对象是同一对象。

如果你想复制一个对象,通常的语法是y = x.copy()y = set(x)。然而,这只是一个副本:虽然它复制了集合对象,但所述对象的成员并未被复制。如果你想要一个深拷贝,请使用copy.deepcopy(x)

【讨论】:

  • 我看不出这两个问题有什么不同。如果集合不可变,y 将指向与 x 不同的对象,就像字符串连接一样。
  • @Codemonkey False:x = "hello"; y = x; y is xTruey = x always 语法使 y 和 x 指向同一个对象。你能解释一下“像字符串连接一样”是什么意思吗?
  • @katrielalex 但是如果你然后进行连接,"y += " world"y 指向与x 不同的对象,而对于可变对象,它不会,这就是他正在做的问题。
  • @agf 对,这是 stdlib 中具有 __i<foo>__ 方法的可变对象的副作用。不能保证可变对象将具有这些,也不保证不可变对象不会。这是一个实现细节。
  • 您不能分配给s[2],因为集合没有排序。不过,您可以使用s.add(4) 将 4 添加到集合中。
【解决方案3】:

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 中删除项目。如果 item 不是 s 的成员,则什么也不会发生。

所有这些操作都在原地修改集合。参数 t 可以是任何支持迭代的对象。

【讨论】:

    【解决方案4】:

    更改集合后,即使它们的对象引用也匹配。我不知道为什么那本教科书说集合是不可变的。

        >>> s1 ={1,2,3}
        >>> id(s1)
        140061513171016
        >>> s1|={5,6,7}
        >>> s1
        {1, 2, 3, 5, 6, 7}
        >>> id(s1)
        140061513171016
    

    【讨论】:

    • 这是哪本教科书?
    • Mark Lutz 的《学习 python》(第 5 版)。也许教科书指的是当时发布的某个python版本。
    • 如果你真的想要不可变集合,python 中有一个叫做“frozenset”的东西,集合具有不可变性。
    • 教科书参考是指pawandeep singh's answer吗?其中包含来自教科书的屏幕截图。
    【解决方案5】:
    print x,y
    

    你会发现它们都指向同一个集合:

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

    【讨论】:

      【解决方案6】:

      集合是可变的

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

      我们可以改变集合的元素

      【讨论】:

        【解决方案7】:

        是的,Python 集合是可变的,因为我们可以在集合中添加、删除元素,但集合本身不能包含可变项。像下面的代码会报错:

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

        所以集合是可变的,但不能包含可变项,因为集合内部使用哈希表来存储其元素,因此集合元素需要是可哈希的。 但是像列表这样的可变元素是不可哈希的。

        注意:
        可变元素不可散列
        不可变元素可散列

        就像字典的键不能是列表一样。

        【讨论】:

          【解决方案8】:

          我不认为 Python 集合是可变的,正如 Mark Lutz 的《Learning Python 第 5 版 - O'Reilly Publications》一书中明确提到的那样

          【讨论】:

          • 集合的元素是不可变的,集合本身是可变的。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-08-09
          • 1970-01-01
          • 1970-01-01
          • 2017-02-13
          • 1970-01-01
          • 2012-01-19
          • 2011-03-11
          相关资源
          最近更新 更多