字典与集合的区别(Python)

100

所以,我知道这件事,

a = {}  # dict
构造一个空字典。现在,我还注意到这个,
b = {1, 2, 3}  # set
创建一个集合。这可以很容易地验证,因为,
>>>print(type(a))
<class 'dict'>

>>>print(type(b))
<class 'set'>

我了解它的功能,但不理解为什么我们要使用空字典的“集合表示法”。我在手册的setdict部分查找了一些关于其逻辑背后的信息,但很遗憾,没有得到任何有用的答案。请问是否有人能够向我解释一下这样做的原因?这是出于历史原因呢,还是我漏看了一些显而易见的东西?


30
一个set类似于一个带有键但没有值的dict,它们都使用哈希表实现。但是,确实有点让人困惑的是,{}符号表示一个空的dict而不是一个空的set,但这是历史遗留问题。我曾经看到过一个建议,即{:}应该是空的dict,而{}则表示空的set,但我怀疑这将很难被实现,因为它会与太多现有代码产生冲突。 - PM 2Ring
@PM2Ring,谢谢!我肯定会支持这个想法,因为我觉得当前的情况(除了语言定义外,它非常清楚,我猜)在阅读时有点模糊不清。 - Nelewout
4
说实话,我觉得很容易记住 {} 是一个空的 dict,因为 Python 一直都有 dict,因为它们对 Python 工作方式非常基本:普通对象属性存储在 dict 中,变量的行为就像是 dict 中的名称: 值对(尽管出于效率原因它们不一定是这样实现的)。而集合 set 则是在语言中添加得很晚的。(当然,在那之前,可以通过使用带有虚拟值的 dict 来“模拟” set)。 - PM 2Ring
4个回答

84
在Python 2中没有"set literals"的概念,从历史上看,花括号只用于字典。可以从列表(或任何可迭代对象)生成集合。
set([1, 2, 3])
set([i for i in range(1, 3)])

创建一个空集合,使用
my_set = set()

Python 3 引入了集合字面量和推导式(参见PEP-3100),使我们能够避免使用中间列表。
{1, 2, 3}
{i for i in range(1, 3)}

然而,空集合形式由于向后兼容性而保留给字典使用。来自[Python-3000] sets in P3K?的引用如下:

我相信我们可以找到一个解决办法---我同意,对于空集合使用{},对于空字典使用{:}是理想的,如果不考虑向后兼容性的话。当我第一次写PEP时,我喜欢“特殊空对象”的想法(即,{}可以变成集合或字典),但这里的一位教员说服我,这只会让新手感到困惑(同时实现起来也很麻烦)。

以下信息更好地描述了这些规则:

我认为Guido提供了最好的解决方案。对于空集合,使用set();对于空字典,使用{};对于集合推导式/显示,使用{genexp};对于显式集合字面量,使用{1,2,3};对于字典字面量,使用{k1:v1, k2:v2}。如果需求超过厌恶,我们随时可以添加{/}

1
虽然所有发布的答案都非常有帮助,但我个人认为这个最能回答我的问题。感谢提供那个PEP的参考,我自己还没有找到它。 - Nelewout
确实可以在Py2.7中使用:https://docs.python.org/3/whatsnew/2.7.html#python-3-1-features - DylanYoung

26
语法不同。字典使用花括号,您需要指定键值对,其中键和值由冒号分隔:
>>> {'foo': 'bar'}
{'foo': 'bar'}
>>> type(_)
<type 'dict'>

后来,该语言添加了集合(Sets),花括号符号{..}只是命名元素,而不是成对出现的元素。
>>> {'foo'}
set(['foo'])
>>> type(_)
<type 'set'>

请注意,在Python 2中,解释器使用set()可调用对象回显对象。这也是指定集合的方式:
>>> emptyset = set()

在Python 3中,当输出对象时,使用新的{..}表示法,除非它为空。
>>> {'foo'}
{'foo'}
>>> _ - {'foo'}  # difference, removing the one element
set()

“set()”类型是在Python语言的2.4版本中添加的(请参见PEP 218),花括号语法用于集合字面量在Python 3中被添加,并且回溯到Python 2.7

17
使用 {} 表示空字典,而不是空集合,这主要是由于历史原因。Python 字典的语法 {'a': 100, 'b': 200} 一直存在于 Python 的早期版本中。而 Python 2.7 中引入了表示集合的语法 {1, 2, 3}。由于 {} 已经被使用了很长时间,所以它将继续作为空字典的定义方式。如果 Python 一开始就有了新的集合语法,可能空集合会被定义为 {},而空字典则会被定义为 {:}

0

集合是一个无序的集合。字典是一种无序的数据集合,它以键值对的形式存储数据。为了实现O(1)的查找和插入操作,字典和集合使用哈希表。 可参考数据结构文档:https://docs.python.org/3/tutorial/datastructures.html

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接