web-dev-qa-db-fra.com

Comment extraire le député de Sing-Member Set in Python?

J'ai récemment rencontré un scénario dans lequel si un ensemble contenait un seul élément, je voulais faire quelque chose avec cet élément. Pour obtenir l'élément, je me suis installé sur cette approche:

element = list(myset)[0]

Mais ce n'est pas très satisfaisant, car cela crée une liste inutile. Cela pourrait également être fait avec itération, mais l'itération semble également non naturelle, car il n'y a qu'un seul élément. Est-ce que je manque quelque chose de simple?

56
recursive

Tuple déballage fonctionne.

(element,) = myset

(Au fait, Python-Dev a exploré mais rejeté l'ajout de myset.get() pour renvoyer un élément arbitraire d'un ensemble. discussion ici , Guido Van Rossum répond 1 et 2 .)

Mon favori personnel pour obtenir un élément arbitraire est (lorsque vous avez un numéro inconnu, mais travaille également si vous en avez une seule):

element = next(iter(myset)) ¹

1 : IN Python 2.5 et avant, vous devez utiliser iter(myset).next()

82
u0b34a0f6ae

Entre faire un tuple et faire un itérateur, c'est presque un lavage, mais l'itération gagne par un nez ...:

$ python2.6 -mtimeit -s'x=set([1])' 'a=Tuple(x)[0]'
1000000 loops, best of 3: 0.465 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a=Tuple(x)[0]'
1000000 loops, best of 3: 0.465 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a=next(iter(x))'
1000000 loops, best of 3: 0.456 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a=next(iter(x))'
1000000 loops, best of 3: 0.456 usec per loop

Je ne sais pas pourquoi toutes les réponses utilisent la syntaxe plus ancienne iter(x).next() plutôt que la nouvelle next(iter(x)), qui semble préférable pour moi (et fonctionne également dans Python = 3.1).

Cependant, le déballage gagne la main sur les deux:

$ python2.6 -mtimeit -s'x=set([1])' 'a,=x'
10000000 loops, best of 3: 0.174 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a,=x'
10000000 loops, best of 3: 0.174 usec per loop

Ceci est bien sûr destiné à des ensembles d'éléments monocommandés (où la fin de cette dernière forme, comme d'autres personnes mentionnées, a l'avantage d'échouer rapidement si le jeu que vous avez "savait" n'avait qu'un seul article en avait effectivement plusieurs). Pour les ensembles avec des éléments n> 1 arbitraires, le tuple ralentit, le iTER ne:

$ python2.6 -mtimeit -s'x=set(range(99))' 'a=next(iter(x))'
1000000 loops, best of 3: 0.417 usec per loop
$ python2.6 -mtimeit -s'x=set(range(99))' 'a=Tuple(x)[0]'
100000 loops, best of 3: 3.12 usec per loop

Donc, déballage pour l'affaire Singleton et next(iter(x)) Pour le cas général, semble le mieux.

21
Alex Martelli

Je pense la réponse de kaizer.se est super. Mais si votre ensemble pourrait contenir plus d'un élément et que vous souhaitez un élément non so-arbitraire, vous voudrez peut-être utiliser min ou max . Par exemple.:

element = min(myset)

ou:

element = max(myset)

(N'utilisez pas sorted , car cela a des frais généraux inutiles pour cet usage.)

13
Craig McQueen

Je suggère:

element = myset.pop()
4
Helmut