web-dev-qa-db-fra.com

Différence entre dict et set (python)

Donc, je sais que ça,

a = {}  # dict

Construit un dictionnaire vide. Maintenant, j'ai aussi compris que ça,

b = {1, 2, 3}  # set

Crée un ensemble. Cela peut facilement être vérifié, comme,

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

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

Bien que je comprenne ce que cela fait, je ne vois pas pourquoi nous utilisons la même syntaxe pour les ensembles et les dictionnaires. J'ai essayé de trouver plus d'informations sur la logique derrière cela dans les sections set et dict du manuel, mais malheureusement, rien obtenu de ça.

Quelqu'un pourrait-il m'expliquer pourquoi nous procédons de la sorte? Est-ce pour des raisons historiques ou est-ce que je manque quelque chose de flagrant?

37
N. Wouda

Il n'y avait pas de littéraux définis dans Python 2, les accolades étaient traditionnellement utilisées pour les dictionnaires. Les ensembles pouvaient être produits à partir listes (ou tout itérables):

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

Python 3 a introduit les littéraux de jeu et les compréhensions (voir PEP-31 ) qui nous permettaient d'éviter les listes intermédiaires:

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

La forme d'ensemble vide, cependant, était réservée aux dictionnaires pour des raisons de compatibilité ascendante. Les références de [Python-3000] définit dans P3K? déclare:

Je suis sûr que nous pouvons trouver une solution --- je suis d’accord, {} Pour un ensemble vide et {:} Pour un dict vide serait idéal, s’il n’ya pas de compatibilité ascendante. J’ai aimé l’idée "d’objet vide spécial" quand j’ai écrit le PEP pour la première fois (c’est-à-dire que {} Pourrait devenir un ensemble ou un dict), mais un des instructeurs ici m’a convaincu qu’il semer la confusion dans l’esprit des nouveaux arrivants (et la mettre en œuvre avec peine).

Le message suivant décrit mieux ces règles:

Je pense que Guido avait la meilleure solution. Utilisez set() pour les ensembles vides, utilisez {} Pour les dict vides, utilisez {genexp} Pour les ensembles compréhensions/affichages, utilisez {1,2,3} Pour les littéraux de jeux explicites, et utilisez {k1:v1, k2:v2} Pour les dictals. Nous pouvons toujours ajouter {/} Plus tard si la demande dépasse le dégoût.

32
myaut

La syntaxe est pas identique. Les dictionnaires ont utilisé des accolades le premier et vous spécifiez des paires clé-valeur, la clé et la valeur étant séparées par un signe deux-points:

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

Les ensembles ont été ajoutés à la langue ultérieurement, et la notation {..} Entre accolades ne contient que des noms éléments, pas des paires:

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

Notez que dans Python 2, l'interpréteur renvoie l'objet à l'aide de l'appelable set()]. C'est également comme cela que vous spécifiez un vide:

>>> emptyset = set()

Dans Python 3, la nouvelle notation {..} Est utilisée lors de l'écho de l'objet, à moins qu'il ne soit vide:

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

Le type set() a été ajouté au Python de version 2.4 (voir PEP 218 ), l'accolade la syntaxe pour les littéraux d'ensemble était ajouté dans Python et porté en arrière à Python 2.7 .

12
Martijn Pieters

Le fait que {} est utilisé pour un dictionnaire vide et non pour un ensemble vide pour des raisons essentiellement historiques. La syntaxe {'a': 100, 'b': 200} pour les dictionnaires existe depuis le début de Python. La syntaxe {1, 2, 3} pour les ensembles a été introduit avec Python 2.7. Depuis {} est utilisé depuis si longtemps qu'il restera comme moyen de définir un dictionnaire vide. Si Python aurait eu la nouvelle syntaxe d'ensemble depuis le début, un ensemble vide serait probablement défini avec {} et un dictionnaire vide avec {:}.

6
Mike Müller