Quelle est la "manière [...] la plus évidente" d'ajouter tous les éléments d'un itérable à un existant set
?
python
set
conventions
iterable
Ian Mackinnon
la source
la source
set
constructeur prend un itérable comme argument.{1, 2, 3}
en Python 3 alors qu'elle étaitset([1, 2, 3])
en Python 2.Pour le bénéfice de tous ceux qui pourraient croire, par exemple, que faire
aset.add()
en boucle aurait des performances compétitives avec le faireaset.update()
, voici un exemple de la façon dont vous pouvez tester rapidement vos croyances avant de devenir public:On dirait que le coût par élément de l'approche en boucle est plus de TROIS fois celui de l'
update
approche.L'utilisation
|= set()
coûte environ 1,5 fois ce queupdate
fait mais la moitié de ce que fait l'ajout de chaque élément individuel dans une boucle.la source
Vous pouvez utiliser la fonction set () pour convertir un itérable en un ensemble, puis utiliser l'opérateur de mise à jour de l'ensemble standard (| =) pour ajouter les valeurs uniques de votre nouvel ensemble à l'existant.
la source
.update
a l'avantage que l'argument peut être n'importe quel itérable - pas nécessairement un ensemble - contrairement au RHS de l'|=
opérateur dans votre exemple.|
pour l'union,&
pour l'intersection et^
pour obtenir des éléments qui sont dans l'un ou l'autre mais pas les deux. Mais dans un langage typé dynamiquement où il est parfois difficile de lire le code et de connaître les types d'objets qui volent, j'hésite à utiliser ces opérateurs. Quelqu'un qui ne les reconnaît pas (ou ne se rend peut-être pas compte que Python autorise des opérateurs comme ceux-ci) pourrait être confus et penser que des opérations binaires ou logiques étranges sont en cours. Ce serait bien si ces opérateurs travaillaient aussi sur d'autres itérables ....update()
et ajouter des éléments individuels dans une boucle. J'ai trouvé que.update()
c'était plus rapide. J'ai ajouté mes résultats à cette réponse existante: stackoverflow.com/a/4046249/901641Juste une mise à jour rapide, timings utilisant python 3:
les résultats sont:
la source
Utilisez la compréhension de liste.
Court-circuiter la création d'itérable à l'aide d'une liste par exemple :)
[Modifier: a manqué la partie définie de la question]
la source
Pour mémoire, je pense que l'affirmation selon laquelle "il devrait y avoir une - et de préférence une seule - façon évidente de le faire." est faux. Cela suppose que de nombreuses personnes à l'esprit technique font, que tout le monde pense de la même manière. Ce qui est évident pour une personne ne l'est pas pour une autre.
Je dirais que ma solution proposée est clairement lisible et fait ce que vous demandez. Je ne pense pas qu'il y ait de succès en termes de performance - même si j'admets que je manque peut-être quelque chose. Mais malgré tout cela, cela n'est peut-être pas évident et préférable à un autre développeur.
la source
aset.update(iterable)
boucle à la vitesse C alors que lesfor item in iterable: aset.add(item)
boucles à la vitesse Python, avec une recherche de méthode et un appel de méthode (aarrgghh !!) par élément.