为什么{}使用整数但set()不能使用整数?

时间:2019-06-12 14:48:50

标签: python python-3.x set

当我在控制台中键入{5}时,得到的结果是一个集合:

>>> {3}
{3}

set(5)导致错误:

>>> set(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

{} or the set() function can both be used to create sets.。那为什么会这样呢?

2 个答案:

答案 0 :(得分:6)

因为the definition of set是:

class set([iterable])

它不接受单个单个值,而是对值进行一个迭代。例如:

set([5, 6, 7])

在对固定数量的值或变量进行硬编码时,将使用文字:

{'foo', bar, baz()}

一个迭代器想要将其“解包”到集合中时,您将使用set构造函数:

set(baz)
set(foo(bar) for bar in baz)
set(map(foo, baz))

答案 1 :(得分:1)

在多个值上定义集合实例时,则值不一定是具体的。例如,它们可以由生成器延迟计算:

values = (a%1 for a in range(2500000))
my_set1 = set(values)  # values can be *any* iterable type

这可以节省内存,因为set最多只能包含2个值。在出现重复项时将其消除。

如果set将使用单个值,则必须*将惰性可迭代对象解压缩为一个临时元组。中间元组将包含所有2500000个值。

def inefficient_set(*items):  # items is an intermediate tuple
    return set(items)

values = (a%1 for a in range(2500000))
my_set2 = inefficient_set(*values)

set具有可迭代性,因此仅在需要时才使用中间容器。


定义多个值的文字集时,所有值已经是具体的。同样,当您定义一组惰性值的文字时,这些也是具体的。

my_set3 = {0, 1, 0, 1, 0, 1}            # values are known to be concrete
my_set4 = {a%1 for a in range(2500000)} # values are known to be lazy

在这种情况下,需要 iterable 将需要一个无用的中间容器。在{}取各个值的情况下,仅在需要时使用中间容器。


要考虑的重要部分是{...}语法,而set(...)是常规的类型实例化。在Python中,语法是静态的,而类型是动态的。这样可以从{a, b, c, ...}理解力中静态区分出具体值的{... for ... in ...}文字。