简体   繁体   中英

Use curly braces to initialize a Set in Python

I'm learning python, and I have a novice question about initializing sets. Through testing, I've discovered that a set can be initialized like so:

my_set = {'foo', 'bar', 'baz'}

Are there any disadvantages of doing it this way, as opposed to the standard way of:

my_set = set(['foo', 'bar', 'baz'])

or is it just a question of style?

There are two obvious issues with the set literal syntax:

my_set = {'foo', 'bar', 'baz'}
  1. It's not available before Python 2.7

  2. There's no way to express an empty set using that syntax (using {} creates an empty dict)

Those may or may not be important to you.

The section of the docs outlining this syntax is here .

Compare also the difference between {} and set() with a single word argument.

>>> a = set('aardvark')
>>> a
{'d', 'v', 'a', 'r', 'k'} 
>>> b = {'aardvark'}
>>> b
{'aardvark'}

but both a and b are sets of course.

From Python 3 documentation ( the same holds for python 2.7 ):

Curly braces or the set() function can be used to create sets. Note: to create an empty set you have to use set(), not {}; the latter creates an empty dictionary, a data structure that we discuss in the next section.

in python 2.7:

>>> my_set = {'foo', 'bar', 'baz', 'baz', 'foo'}
>>> my_set
set(['bar', 'foo', 'baz'])

Be aware that {} is also used for map / dict :

>>> m = {'a':2,3:'d'}
>>> m[3]
'd'
>>> m={}
>>> type(m)
<type 'dict'> 

One can also use comprehensive syntax to initialize sets:

>>> a = {x for x in """didn't know about {} and sets """ if x not in 'set' }
>>> a
set(['a', ' ', 'b', 'd', "'", 'i', 'k', 'o', 'n', 'u', 'w', '{', '}'])

You need to do empty_set = set() to initialize an empty set. {} is an empty dict .

I'm surprised nobody has mentioned this, but it appears there is actually a difference between those two syntaxes from what I can tell—and that is performance/optimization .

For most situations the difference should be negligible, but in your example the following is creating a set from items directly:

my_set = {'foo', 'bar', 'baz'}

While the following creates a list and then passes it to the set constructor:

my_set = set(['foo', 'bar', 'baz'])

The end results are equivalent, but we're getting them two slightly different ways. As you'd expect, the second one is a bit slower:

❯ python -m timeit 'my_set = {"foo", "bar", "baz"}'
10000000 loops, best of 5: 37.3 nsec per loop

❯ python -m timeit 'my_set = set(["foo", "bar", "baz"])'
5000000 loops, best of 5: 92.3 nsec per loop

As far as I'm aware, the {} literal syntax is the only way to skip creating an intermediate iterable when constructing a set . It's a little odd to me personally that the set constructor wasn't instead designed to take a variable number of positional arguments like so:

# This usage is invalid in real Python. If it existed,
# I would expect the call to be exactly equivalent
# to the performance of the literal syntax.
>>> set("foo", "bar", "baz")

# You would then construct a `set` from an existing
# `list` by simply unpacking the sequence.
>>> set(*["foo", "bar", "baz"])

Unfortunately, that signature doesn't exist.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM