2012-02-15 4 views
34

Qu'est-ce que je fais de mal ici?Ajouter un numéro

a = set().add(1) 
print a # Prints `None` 

Je suis en train d'ajouter le numéro 1 à l'ensemble vide.

+2

@CharlesB Si vous donnez une réponse, alors vous devriez le faire dans une réponse. S'il vous plaît noter qu'il est horriblement impopulaire d'utiliser des points-virgules. Python est censé être lisible, et mettre plusieurs instructions sur une seule ligne est très mauvais pour la lisibilité. –

+0

@GarethLatty: il ne répond pas non plus à la question. – user443854

Répondre

53

C'est une convention en Python que les méthodes qui renvoient des séquences mutantes renvoient None.

Tenir compte:

>>> a_list = [3, 2, 1] 
>>> print a_list.sort() 
None 
>>> a_list 
[1, 2, 3] 

>>> a_dict = {} 
>>> print a_dict.__setitem__('a', 1) 
None 
>>> a_dict 
{'a': 1} 

>>> a_set = set() 
>>> print a_set.add(1) 
None 
>>> a_set 
set([1]) 

Certains peuvent considérer cette convention "une mauvaise conception horrible Python", mais la conception et l'histoire FAQ gives the reasoning derrière cette décision de conception (par rapport aux listes):

Pourquoi list.sort( ne renvoie pas la liste triée?

Dans les situations où la performance compte, faire une copie de la liste juste pour le tri serait inutile. Par conséquent, list.sort() trie la liste en place. Afin de vous rappeler ce fait, il ne renvoie pas la liste triée. De cette façon, vous ne serez pas duper accidentellement écraser une liste lorsque vous avez besoin d'une copie triée, mais aussi besoin de garder la version non triée autour.

En Python 2.4, une nouvelle fonction intégrée - sorted() - a été ajoutée. Cette fonction crée une nouvelle liste à partir d'une itération fournie, la trie et la renvoie.

Vos problèmes particuliers avec cette fonctionnalité proviennent d'une mauvaise compréhension des bons moyens de créer un ensemble plutôt qu'un mauvais langage. En tant que Lattyware points out, dans les versions 2.7 et ultérieures de Python, vous pouvez utiliser un ensemble littéral a = {1} ou faire a = set([1]) selon le answer de Sven Marnach. Entre parenthèses, j'aime la convention de Ruby de placer un point d'exclamation après des méthodes qui muent des objets, mais je trouve l'approche de Python acceptable.

4

Parce que add() est modifing votre jeu en place None retour:

>>> empty = set() 
>>> print(empty.add(1)) 
None 
>>> empty 
set([1]) 
1

Vous devriez faire ceci:

a = set() 
a.add(1) 
print a 

Notez que vous assignant à a le résultat de l'ajout 1, et l'opération add, comme défini dans Python, renvoie None - et c'est ce qui est affecté à a dans votre code.

Alternativement, vous pouvez le faire pour initialiser un ensemble:

a = set([1, 2, 3]) 
24

La méthode add() ajoute un élément à l'ensemble, mais il ne retourne pas le jeu à nouveau - il retourne None.

a = set() 
a.add(1) 

ou mieux

a = set([1]) 

fonctionnerait.

+1

Merci. Cela ressemble à une mauvaise conception horrible en Python. Qu'est-ce que tu penses? – Randomblue

+8

@Randomblue: Je pense que si c'était complètement confus si 'set.add()' renvoyait l'ensemble. Pourquoi devrait-il? La convention est: Si elle change l'objet en place, elle retourne 'None'. S'il crée un nouvel objet, il renvoie le nouvel objet. Juste comme il est censé être. –

+0

@RandomBlue: J'ai créé une réponse pour répondre à votre question de suivi. –

1

La méthode add met à jour l'ensemble, mais renvoie None.

a = set() 
a.add(1) 
print a 
1

Vous assignez la valeur retournée par set().add(1) à un. Cette valeur est None, car add() ne renvoie aucune valeur, il agit à la place sur la liste.

Qu'est-ce que vous vouliez faire était le suivant:

a = set() 
a.add(1) 
print(a) 

Bien sûr, cet exemple est trivial, mais Python supporte littéraux ensemble, donc si vous vouliez vraiment faire cela, il est préférable de le faire:

a = {1} 
print(a) 

les accolades désignent un ensemble (bien attention, {} désigne un vide dict, et non pas un ensemble vide en raison du fait que les accolades sont utilisées aussi bien pour les dicts et ensembles (dicts sont séparés par l'utilisation du côlon pour séparer les clés et les valeurs.)

1

Une autre façon de le faire qui est serait relativement simple être:

a = set() 
a = set() | {1} 

cela crée une union entre votre jeu a et un ensemble avec 1 comme élément

impression (a) les rendements {1 } puis parce que a aurait maintenant tous les éléments de a et {1}

0

Alternativement à a = set() | {1} considérer l'opérateur "sur place":

a = set() 
a |= {1} 
Questions connexes