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

时间:2011-03-08 14:53:10

标签: python list generator

使用我会

var top5 = array.Take(5);

如何使用Python做到这一点?

8 个答案:

答案 0 :(得分:402)

切片列表

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)

答案 1 :(得分:104)

import itertools

top5 = itertools.islice(array, 5)

答案 2 :(得分:30)

根据我的喜好,将'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)

答案 3 :(得分:17)

@ Shaikovsky的答案非常好( ...自从我发布这个答案以后进行了大量编辑),但我想澄清几点。

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

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

另一方面,以下方法会返回最多 n项,这在大多数情况下都是可取的:

表: [x for _, x in zip(range(n), records)]

发电机: (x for _, x in zip(range(n), records))

答案 4 :(得分:12)

可以找到如何执行此操作的答案here

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

请注意,当剩下的只有2个时,最后一个呼叫要求下一个4。使用list()代替[]可以理解终止StopIteration引发的next()异常。

答案 5 :(得分:5)

您的意思是第一个 N个项目,还是N 最大的项目?

如果你想要第一个:

top5 = sequence[:5]

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

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

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

对于更高性能的解决方案,请使用min-heap(感谢Thijs):

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

答案 6 :(得分:3)

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

使用列表理解:

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

否则:

first_N_element=list(generator)[:N]

其中N是您要采用的元素数量(例如前五个元素的N = 5)。

答案 7 :(得分:-5)

这应该有效

top5 = array[:5]