Question

Quelle est la "un [...] de façon évidente" d'ajouter tous les éléments d'un itérables à un set existant?

Était-ce utile?

La solution

Vous pouvez ajouter des éléments d'un list à un set comme ceci:

>>> foo = set(range(0, 4))
>>> foo
set([0, 1, 2, 3])
>>> foo.update(range(2, 6))
>>> foo
set([0, 1, 2, 3, 4, 5])

Autres conseils

Pour le bénéfice de tous ceux qui pourraient croire par exemple que faire aset.add() dans une boucle aurait performance compétitive avec faire aset.update(), voici un exemple de la façon dont vous pouvez tester vos croyances rapidement avant d'aller public:

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "a.update(it)"
1000 loops, best of 3: 294 usec per loop

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "for i in it:a.add(i)"
1000 loops, best of 3: 950 usec per loop

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "a |= set(it)"
1000 loops, best of 3: 458 usec per loop

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "a.update(it)"
1000 loops, best of 3: 598 usec per loop

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "for i in it:a.add(i)"
1000 loops, best of 3: 1.89 msec per loop

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "a |= set(it)"
1000 loops, best of 3: 891 usec per loop

On dirait que le coût par élément de l'approche de la boucle est plus de trois fois celle de l'approche update.

En utilisant les coûts de |= set() à propos de 1,5x ce update fait, mais la moitié de ce que l'ajout de chaque élément individuel dans une boucle fait.

Vous pouvez utiliser l'ensemble () pour convertir un itérable en un ensemble, et ensuite utiliser l'opérateur de mise à jour de jeu standard. (| =) Pour ajouter les valeurs uniques de votre nouveau jeu dans l'existant

>>> a = { 1, 2, 3 }
>>> b = ( 3, 4, 5 )
>>> a |= set(b)
>>> a
set([1, 2, 3, 4, 5])

Juste une rapide mise à jour, les horaires en utilisant Python 3:

#!/usr/local/bin python3
from timeit import Timer

a = set(range(1, 100000))
b = list(range(50000, 150000))

def one_by_one(s, l):
    for i in l:
        s.add(i)    

def cast_to_list_and_back(s, l):
    s = set(list(s) + l)

def update_set(s,l):
    s.update(l)

résultats sont les suivants:

one_by_one 10.184448844986036
cast_to_list_and_back 7.969255169969983
update_set 2.212590195937082

Utiliser la compréhension de la liste.

Court-circuiter la création de itérables en utilisant une liste par exemple:)

>>> x = [1, 2, 3, 4]
>>> 
>>> k = x.__iter__()
>>> k
<listiterator object at 0x100517490>
>>> l = [y for y in k]
>>> l
[1, 2, 3, 4]
>>> 
>>> z = Set([1,2])
>>> z.update(l)
>>> z
set([1, 2, 3, 4])
>>> 

[Edit: manquer la partie de jeu de question]

for item in items:
   extant_set.add(item)

Pour mémoire, je pense que l'affirmation selon laquelle « Il devrait y avoir One-- et de préférence qu'une seule façon --obvious de le faire. » est faux. Il fait une hypothèse que beaucoup de gens d'esprit techniques font, que tout le monde pense aussi bien. Ce qui est évident à une personne n'est pas si évidente à l'autre.

Je dirais que ma solution proposée est clairement lisible, et fait ce que vous demandez. Je ne crois pas qu'il y ait problèmes de performances impliquées dans ce projet - même si je dois admettre que je pourrais manquer quelque chose. Mais malgré tout cela, il pourrait ne pas être évidente et préférable à un autre développeur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top