如何从生成器或列表中获取前N项?

对于,我会

var top5 = array.Take(5);

如何用Python做到这一点?

383423 次浏览
import itertools


top5 = itertools.islice(array, 5)

这应该可以

top5 = array[:5]

你是指__abc0n项,还是N 最大项?

如果你想要第一个:

top5 = sequence[:5]

这也适用于最大的N项,假设您的序列是按降序排序的。(你的LINQ例子似乎也假设了这一点。)

如果你想要最大的,而且它没有排序,最明显的解决方案是先排序:

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

为了获得更高效的解决方案,使用最小堆(感谢Thijs):

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

切片列表

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)

在我看来,将zip()xrange(n)(或Python3中的range(n))结合起来也非常简洁,这在生成器上也很好,而且对于一般的更改似乎更灵活。

# 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)

使用itertools,您将获得另一个生成器对象,因此在大多数情况下,您将需要另一步来获取第一个n元素。至少有两个更简单的解决方案(在性能方面效率稍低,但非常方便)可以从generator中获取可使用的元素:

使用列表推导式:

first_n_elements = [generator.next() for i in range(n)]

否则:

first_n_elements = list(generator)[:n]

其中n是你想要取的元素数量(例如n=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()而不是[]可以让推导式在next()抛出的StopIteration异常上终止。

@Shaikovsky的回答是优秀的,但我想澄清两点。

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

这是最简单的方法,但如果生成器过早耗尽,则抛出StopIteration


另一方面,以下方法返回 n项,这在许多情况下是可取的:

< p >列表: [x for _, x in zip(range(n), records)] < / p > < p >发电机: (x for _, x in zip(range(n), records)) < / p >