top5 = array[:5]
array[start:stop:step]
array[start:]
, array[:stop]
, array[::step]
import itertools
top5 = itertools.islice(my_list, 5) # grab the first five elements
Vous ne pouvez pas découper un générateur directement en Python. itertools.islice()
va envelopper un objet dans un nouveau générateur de découpage en utilisant la syntaxe itertools.islice(generator, start, stop, step)
Rappelez-vous que couper un générateur l’épuisera partiellement. Si vous souhaitez conserver l'intégralité du générateur, commencez par le transformer en tuple ou en liste, par exemple: result = Tuple(generator)
import itertools
top5 = itertools.islice(array, 5)
À mon goût, il est également très concis de combiner "Zip ()" avec "xrange (n)" (ou "range (n)" en Python3), qui fonctionne bien sur les générateurs et semble être plus flexible pour les changements de général.
# Option #1: taking the first n elements as a list
[x for _, x in Zip(xrange(n), generator)]
# Option #2, using 'next()' and taking care for 'StopIteration'
[next(generator) for _ in xrange(n)]
# Option #3: taking the first n elements as a new generator
(x for _, x in Zip(xrange(n), generator))
# Option #4: yielding them by simply preparing a function
# (but take care for 'StopIteration')
def top_n(n, generator):
for _ in xrange(n): yield next(generator)
La réponse de @ Shaikovsky est excellente (… et fortement modifiée depuis que j'ai posté cette réponse ), mais je voulais clarifier quelques points.
[next(generator) for _ in range(n)]
C'est l'approche la plus simple, mais jette StopIteration
si le générateur est épuisé prématurément.
Par ailleurs, les approches suivantes renvoient des éléments jusqu’àn
, ce qui est sans doute préférable dans la plupart des cas:
Liste: [x for _, x in Zip(range(n), records)]
Générateur: (x for _, x in Zip(range(n), records))
La réponse pour savoir comment faire cela peut être trouvée ici
>>> generator = (i for i in xrange(10))
>>> list(next(generator) for _ in range(4))
[0, 1, 2, 3]
>>> list(next(generator) for _ in range(4))
[4, 5, 6, 7]
>>> list(next(generator) for _ in range(4))
[8, 9]
Notez que le dernier appel demande le prochain 4 alors qu'il n'en reste que 2. L'utilisation de list()
au lieu de []
est ce qui permet à la compréhension de se terminer sur l'exception StopIteration
qui est levée par next()
.
Voulez-vous dire les premiers N éléments, ou les N les plus grands?
Si vous voulez le premier:
top5 = sequence[:5]
Cela fonctionne également pour les N éléments les plus grands, en supposant que votre séquence soit triée par ordre décroissant. (Votre exemple LINQ semble le supposer également.)
Si vous voulez le plus gros, et que cela ne soit pas trié, la solution la plus évidente est de le trier en premier:
l = list(sequence)
l.sort(reverse=True)
top5 = l[:5]
Pour une solution plus performante, utilisez un min-tas (merci Thijs):
import heapq
top5 = heapq.nlargest(5, sequence)
Avec itertools
vous obtiendrez un autre objet générateur, de sorte que dans la plupart des cas, vous aurez besoin d'une autre étape pour prendre les N premiers éléments (N
). Il existe au moins deux solutions plus simples (un peu moins efficace en termes de performances mais très pratique) pour obtenir les éléments prêts à être utilisés à partir d'un generator
:
Utilisation de la compréhension de liste:
first_N_element=[generator.next() for i in range(N)]
Autrement:
first_N_element=list(generator)[:N]
Où N
est le nombre d'éléments à prendre (par exemple, N = 5 pour les cinq premiers éléments).