Как перенести первые N элементов из генератора или списка в Python?

С Я бы

var top5 = array.Take(5);

Как это сделать с Python?

Ответ 1

Нарезка списка

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
  • Вы не можете нарезать генератор прямо на Python. itertools.islice() перенесет объект в новый генератор среза, используя синтаксис itertools.islice(generator, start, stop, step)

  • Помните, что нарезка генератора частично исчерпает его. Если вы хотите, чтобы весь генератор оставался нетронутым, возможно, сначала переведите его в кортеж или список, например: result = tuple(generator)

Ответ 2

import itertools

top5 = itertools.islice(array, 5)

Ответ 3

В моем вкусе также очень кратким сочетать zip() с диапазоном (n), который хорошо работает и на генераторах, и, кажется, более гибкий для изменений в целом.

В Python 3 оба типа zip() и range() являются генераторами. В Python 2 вы можете получить верхние элементы для создания генератора.

# taking the first n elements as a list
[x for _, x in zip(range(n), generator)]

# or, alternatively
[next(generator) for _ in range(n)]

# taking the first n elements as a new generator
# (can work great in Python 3, since zip() and range() are generators)
(x for _, x in zip(range(n), generator))

# or yielding them by simply preparing a function
def top_n(n, generator):
    for _ in range(n): yield next(generator)

Ответ 4

@Ответ Шайковского отличный, но я хотел уточнить пару пунктов.

[next(generator) for _ in range(n)]

Это самый простой подход, но бросает StopIteration, если генератор преждевременно исчерпан.


С другой стороны, следующие подходы возвращают элементы до n, которые, возможно, предпочтительнее в большинстве случаев:

Список: [x for _, x in zip(range(n), records)]

Генератор: (x for _, x in zip(range(n), records))

Ответ 5

Ответ на вопрос о том, как это сделать, можно найти здесь

>>> 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]

Обратите внимание, что последний вызов запрашивает следующие 4, когда осталось только 2. Использование list() вместо [] - это то, что получает понимание для завершения в исключении StopIteration, которое выбрано next().

Ответ 6

Вы имеете в виду первые N элементов или N наибольших предметов?

Если вы хотите первый:

top5 = sequence[:5]

Это также работает для самых больших N элементов, предполагая, что ваша последовательность сортируется в порядке убывания. (Возможно, и ваш пример LINQ).

Если вам нужен самый большой и он не отсортирован, наиболее очевидным решением является его сортировка в первую очередь:

l = list(sequence)
l.sort(reverse=True)
top5 = l[:5]

Для более эффективного решения используйте мини-кучу (спасибо Thijs):

import heapq
top5 = heapq.nlargest(5, sequence)

Ответ 7

С помощью itertools вы получите еще один объект-генератор, поэтому в большинстве случаев вам понадобится еще один шаг: возьмите первые N элементов (N). Есть как минимум два простых решения (немного менее эффективные с точки зрения производительности, но очень удобные), чтобы получить готовые элементы из generator:

Использование списка:

first_N_element=[generator.next() for i in range(N)]

В противном случае:

first_N_element=list(generator)[:N]

Где N - количество элементов, которые вы хотите принять (например, N = 5 для первых пяти элементов).

Ответ 8

Это должно работать

top5 = array[:5] 

Ответ 9

Вы должны использовать срезы:

Попробуйте следующее:

>>> lst = [1,2,3,4,5]

>>> lst[:2]
[1, 2]

Требуется от индекса 0 к индексу 2.

Вы также можете делать такие вещи, как:

>>> lst = [1,2,3,4,5]

>>> lst[2:4]

[3, 4]