如何从Python中的生成器或列表中获取前N个项目?
切片列表
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)
另请注意,'itertools.islice'将返回一个生成器。 – 2014-02-01 02:06:49
为什么你会变得复杂?只要扔'my_list [:5]',我们所有的生活现在简单 – OverCoder 2016-06-11 02:00:01
问题是“生成器或列表”。这些有两个不同的答案。 'islice'对列表来说是错误的答案,但对于一个生成器来说是正确的答案。我清理了一些答案,以便更清楚地说明问题。 – lunixbochs 2016-06-11 04:18:23
这应该工作
top5 = array[:5]
你的意思是第一 N项,或者N 最大项目?
如果你想第一:
top5 = sequence[:5]
这也适用于最大的N个项目,假设你的顺序降序排列。 (你的LINQ例子似乎承担这一以及)
如果你想最大的,它是没有排序,最明显的解决方案是先解决它:
l = list(sequence)
l.sort(reverse=True)
top5 = l[:5]
对于一个更好的性能解决方案,采用最小堆(感谢泰斯):
import heapq
top5 = heapq.nlargest(5, sequence)
不会先小吗? – 2011-03-08 15:32:36
呃,哎呀。将解决。 – Thomas 2011-03-08 21:57:53
+1用于回答,尽管问题明显含糊 – demongolem 2012-11-01 23:35:45
你必须使用切片:
试试这个:
>>> lst = [1,2,3,4,5]
>>> lst[:2]
[1, 2]
它从索引0到索引2
你也可以做这样的事情:
>>> lst = [1,2,3,4,5]
>>> lst[2:4]
[3, 4]
在我的口味,它也很简洁结合“拉链()”与“x范围(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个元素(N
)。有至少两个简单的解决方案(一点点效率较低的性能,但非常方便的术语),以准备好从generator
使用的元素:
使用列表理解:
first_N_element=[generator.next() for i in range(N)]
否则:
first_N_element=list(generator)[:N]
N
其中N
是你想要的元素的数量(例如前五个元素的N = 5)。
如何做到这一点的答案可以发现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]
注意,最后一次通话要求下一个4时只有2个被剩下。 list()
而不是[]
的用法是理解终止于由next()
抛出的StopIteration
异常。
@ 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))
难道那些少数人下调这个答案,请解释为什么? – 2018-02-05 11:49:52
它混淆了这个问题被要求提供列表和生成器,这些应该是单独的q问题 – ThorSummoner 2017-05-23 17:24:12