Difference between dict and set (python)
Asked Answered
G

3

101

So, I know that this,

a = {}  # dict

constructs an empty dictionary. Now, I also picked up that this,

b = {1, 2, 3}  # set

creates a set. This can easily be verified, as,

>>>print(type(a))
<class 'dict'>

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

While I understand what it does, I fail to see why we use 'set notation' for empty dictionaries. I tried to find some more information about the logic behind this in the set and dict sections of the manual, but sadly, I got nothing out of it.

Could anyone explain to me why we do this in this way? Is it for historical reasons, or am I missing something blatantly obvious?

Greatuncle answered 19/12, 2015 at 12:13 Comment(3)
Well, a set is like a dict with keys but no values, and they're both implemented using a hash table. But yes, it's a little annoying that the {} notation denotes an empty dict rather than an empty set, but that's a historical artifact. I've seen a suggestion that {:} should be an empty dict and {} an empty set, but I doubt that'll ever be implemented, as it clashes with too much existing code.Montoya
@PM2Ring, thank you! I'd definitely support that, as I feel the current situation (apart from the language definition, which is very clear about it, I guess) reads as a bit ambiguous.Greatuncle
FWIW, I find it easy to remember that {} is an empty dict because Python has always had dicts, since they're fundamental to the way Python works: normal object attributes are stored in a dict, and variables behave as if they are name:value pairs in a dict (although they aren't necessarily implemented that way for efficiency reasons). Whereas sets were added to the language quite a while later. (Of course, before then it was always possible to "fake" a set by using a dict with dummy values).Montoya
P
85

There were no set literals in Python 2, historically curly braces were only used for dictionaries. Sets could be produced from lists (or any iterables):

set([1, 2, 3])
set([i for i in range(1, 3)])

To create an empty set, use

my_set = set()

Python 3 introduced set literals and comprehensions (see PEP-3100) which allowed us to avoid intermediate lists:

{1, 2, 3}
{i for i in range(1, 3)}

The empty set form, however, was reserved for dictionaries due to backwards compatibility. References from [Python-3000] sets in P3K? states:

I'm sure we can work something out --- I agree, {} for empty set and {:} for empty dict would be ideal, were it not for backward compatibility. I liked the "special empty object" idea when I first wrote the PEP (i.e., have {} be something that could turn into either a set or dict), but one of the instructors here convinced me that it would just lead to confusion in newcomers' minds (as well as being a pain to implement).

The following message describes these rules better:

I think Guido had the best solution. Use set() for empty sets, use {} for empty dicts, use {genexp} for set comprehensions/displays, use {1,2,3} for explicit set literals, and use {k1:v1, k2:v2} for dict literals. We can always add {/} later if demand exceeds distaste.

Pelota answered 19/12, 2015 at 12:25 Comment(2)
While all answers posted are really helpful, I personally feel this one best answers my question. Thanks for the references to that PEP, I had not found it myself yet.Greatuncle
Is indeed available in Py2.7: docs.python.org/3/whatsnew/2.7.html#python-3-1-featuresGarrard
D
26

The syntax is not the same. Dictionaries used curly braces the first and you specify key-value pairs, where the key and value are separated by a colon:

>>> {'foo': 'bar'}
{'foo': 'bar'}
>>> type(_)
<type 'dict'>

Sets were added to the language later on, and the {..} curly brace notation only names elements, not pairs:

>>> {'foo'}
set(['foo'])
>>> type(_)
<type 'set'>

Note that in Python 2, the interpreter echoes the object using the set() callable. That's also how you specify an empty set:

>>> emptyset = set()

In Python 3, the newer {..} notation is used when echoing the object, unless it is empty:

>>> {'foo'}
{'foo'}
>>> _ - {'foo'}  # difference, removing the one element
set()

The set() type was added to the Python language in version 2.4 (see PEP 218), the curly brace syntax for set literals was added in Python 3 and back-ported to Python 2.7.

Debbiedebbra answered 19/12, 2015 at 12:16 Comment(0)
B
17

The fact that {} is used for an empty dictionary and not for an empty set has largely historical reasons. The syntax {'a': 100, 'b': 200} for dictionaries has been around since the beginning of Python. The syntax {1, 2, 3} for sets was introduced with Python 2.7. Since {} has been used for such a long time it will stay as the way to define an empty dictionary. If Python would have had the new set syntax since the beginning, likely an empty set would be defined with {} and an empty dictionary with {:}.

Be answered 19/12, 2015 at 12:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.