如果pythonset不允许可变对象,那么为什么它允许添加带有单个元素的列表呢

如果pythonset不允许可变对象,那么为什么它允许添加带有单个元素的列表呢,python,Python,我读了一篇: 集合的实现方式不允许可变对象 当我执行: cities = set((["Python","Perl"], ["Paris", "Berlin", "London"])) 它抛出错误: TypeError:列表对象不可损坏 我搜索了这个错误,了解到set不允许可变对象,因此它抛出了这个错误。但正如您所看到的,集合中的元素是一个元组,它是不可变的,所以集合应该允许它。使用type()检查 但当我尝试时: cities = set((["Python","Perl"])) 即使集

我读了一篇:

集合的实现方式不允许可变对象

当我执行:

 cities = set((["Python","Perl"], ["Paris", "Berlin", "London"]))
它抛出错误:

TypeError:列表对象不可损坏

我搜索了这个错误,了解到set不允许可变对象,因此它抛出了这个错误。但正如您所看到的,集合中的元素是一个元组,它是不可变的,所以集合应该允许它。使用
type()检查
但当我尝试时:

cities = set((["Python","Perl"]))
即使集合中的元素是可变列表,它也可以工作。 我真的很困惑。 我现在很困惑-(

即使集合中的元素是可变列表,它也可以工作

您正在使用单个参数
([“Python”,“Perl”])
初始化集合,该参数与
[“Python”,“Perl”]
相同,即字符串列表

集合解压此列表,留下两个类型为
str
的元素:

>>> cities = set((["Python","Perl"]))
>>> for c in cities: print type(c), c
<type 'str'> Python
<type 'str'> Perl
城市=集合(([“Python”,“Perl”])) >>>对于城市中的c:打印类型(c),c python Perl
首先,hashable和immutable不是一回事。包含hashable的定义:

如果一个对象的哈希值在其生存期内从未改变(它需要一个哈希()方法),并且可以与其他对象进行比较(它需要一个eq()或cmp()),则该对象是可哈希的。比较相等的可哈希对象必须具有相同的哈希值

哈希性使对象可用作字典键和集合成员,因为这些数据结构在内部使用哈希值

Python的所有不可变内置对象都是可散列的,而没有可变容器(如列表或字典)是可散列的。默认情况下,作为用户定义类实例的对象是可散列的;它们都比较不相等(除了它们自己),并且它们的散列值是它们的id()

如您所见,任何实现
\uuuuuuuu hash\uuuuuuu
\uuuuuueq\uuuu
\uuuuu cmp\uuuuu
的对象都可以添加到一个集合中。为高度可变的对象(如列表)实现这些方法的智慧是值得怀疑的,但它是可以做到的。不变性决不是一个要求


其次,可以从列表中初始化一个集合,只要每个元素都可以散列。行
cities=set(([“Python”,“Perl”])
构造一个集合,其中
Python
Perl
作为元素。请注意,额外的括号不会创建元组。添加额外的逗号,
cities=set([“Python”,“Perl”]))
会给您带来与以前相同的错误,因为现在您将拥有一个元组。在这种情况下,元组尝试计算哈希,但其哈希取决于列表的哈希,而列表的哈希并不存在。

如果您想在示例中获得元组的元组,您应该尝试:

cities = set((("Python","Perl"), ("Paris", "Berlin", "London")))
print cities #Output set([('Paris', 'Berlin', 'London'), ('Python', 'Perl')])
type(cities) #Output <type 'set'>
cities=set(((“Python”、“Perl”)、(“巴黎”、“柏林”、“伦敦”))
打印城市#输出集([('Paris','Berlin','London'),('Python','Perl'))
类型(城市)#产量

尝试检查集合元素的类型。