为什么有时可以用{}替换set()?


73

在PyCharm中,当我写时:

return set([(sy + ady, sx + adx)])

它说“函数调用可以用设置文字代替”,因此将其替换为:

return {(sy + ady, sx + adx)}

这是为什么?set()Python中的A与字典不同{}吗?

如果要优化它,为什么它更有效?


6
需要注意的是,尽管你的标题,你不能代替set(){},但你可以替换非空set((1, 2, 3))与文字{1, 2, 3},因为现在很明显,这不是一本字典。请参阅docs.python.org/2/library/stdtypes.html#set-types-set-frozenset
jonrsharpe

Answers:


105

Python集和字典都可以使用大括号构造:

my_dict = {'a': 1, 'b': 2}

my_set = {1, 2, 3}

口译员(和普通读者)可以根据其内容来区分它们。但是,不可能区分空集和空dict,因此这种情况下您需要使用set()空集来消除歧义。

一个非常简单的测试表明,文字构造的速度更快(python3.5):

>>> timeit.timeit('a = set([1, 2, 3])')
0.5449375328607857
>>> timeit.timeit('a = {1, 2, 3}')
0.20525191631168127

这个问题涵盖了内置函数的文字构造的一些性能问题,即使是列表和字典也是如此。总结似乎是文字构造需要较少的解释器工作。


文字构造可能会更快,因为您不需要建立中间列表。如果您将其排除在外怎么办?
jonrsharpe

4
@jonrsharpe似乎仍然较慢:timeit.timeit(stmt='a = set(mylist)', setup='mylist=[1, 2, 3]') -> 0.3987466390244663-我认为我添加的链接涵盖了部分内容。
snakecharmerb '16

哇,在Python3.8中,尝试进行测试,两者之间的区别令人印象深刻:0.1970vs0.0705
Olivier Pons

9

它是 set()

>>> a = {1, 2}
>>> b = set()
>>> b.add(1)
>>> b.add(2)
>>> b
set([1, 2])
>>> a
set([1, 2])
>>> a == b
True
>>> type(a) == type(b)
True

dict语法不同。它由键值对组成。例如:

my_obj = {1:None, 2:None}

4

set([iterable])是从可选iterable创建集合的构造函数iterable。并且{}是创建set / dict对象的文字。因此,创建的内容取决于您的使用方式。

In [414]: x = {}

In [415]: type(x)
Out[415]: dict

In [416]: x = {1}

In [417]: type(x)
Out[417]: set

In [418]: x = {1: "hello"}

In [419]: type(x)
Out[419]: dict

当您说的set([iterable])时候,您的意思是文字[]出现吗?还是使用ABNF表示iterable该函数的可选参数set()?因为第一种情况是错误的,所以第二种情况是正确的。这很令人困惑,因为许多人会读到这并认为您是第一种情况。
布格

4

又如如何set{}不能互换(如jonrsharpe提及):

In: f = 'FH'

In: set(f)
Out: {'F', 'H'}

In: {f}
Out: {'FH'}

1
set(f)带文字的功能必须使用拆包:{*f}
IFcoltransG

这是从来没有可以替换set(somestuff)使用{somestuff}。但是set([somestuff]){somestuff}只要somestuff源代码中的字面不是0个字符,就可以用替换。由于OP正在使用set([somestuff])并且somestuff不是0个字符,因此可以替换。
布格
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.