lun*_*chs 446

切片列表

top5 = array[:5]
Run Code Online (Sandbox Code Playgroud)
  • 要切片列表,有一个简单的语法: array[start:stop:step]
  • 您可以省略任何参数.这些都是有效的:array[start:],array[:stop],array[::step]

切片发电机

 import itertools
 top5 = itertools.islice(my_list, 5) # grab the first five elements
Run Code Online (Sandbox Code Playgroud)
  • 你不能直接在Python中切片生成器.itertools.islice()将使用语法将对象包装在新的切片生成器中itertools.islice(generator, start, stop, step)

  • 请记住,切割发电机会使其部分耗尽.如果你想保持整个生成器的完整性,可能先把它变成一个元组或列表,如:result = tuple(generator)

  • 另请注意,`itertools.islice`将返回一个生成器. (35认同)
  • 问题是"生成器或列表".这有两个不同的答案.`islice`是列表的错误答案,但是对于生成器来说是正确的答案.我稍微清理了一下这个答案,以便更清楚. (19认同)
  • 要在耗尽生成器之前创建生成器的副本,您还可以使用 [itertools.tee](https://docs.python.org/3/library/itertools.html#itertools.tee),例如: `generator, another_copy = itertools.tee(生成器)` (4认同)
  • “如果您想保持整个生成器完整无缺,也许可以先将其转换为元组或列表”-> 在构建元组/列表的过程中,这不会完全耗尽生成器吗? (3认同)
  • @lucid_dreamer是的,但是您有了一个新的数据结构(元组/列表),可以根据需要进行多次迭代 (2认同)

Jad*_*ias 108

import itertools

top5 = itertools.islice(array, 5)
Run Code Online (Sandbox Code Playgroud)

  • 当你用None代替5时,这也有很好的返回整个数组的属性. (3认同)
  • 这是以下使用的方法:[Itertools recipes](https://docs.python.org/3/library/itertools.html#itertools-recipes) `def take(n, iterable): return list(islice(可迭代,n))` (3认同)
  • 如果你想每次使用下面的五个,你可以使用:iter(数组)而不是数组. (2认同)

小智 33

根据我的喜好,将'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)
Run Code Online (Sandbox Code Playgroud)


Bed*_*des 24

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

  • 那些对这个答案投反对票的人能否解释一下原因? (2认同)
  • 这是最有效率的。因为这不会处理完整列表。 (2认同)
  • `[next(generator, None) for _ in range(n)]` 如果你不介意 `None` (2认同)

小智 13

这里可以找到如何做到这一点的答案

>>> 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]
Run Code Online (Sandbox Code Playgroud)

请注意,当剩下的只有2个时,最后一个呼叫要求下一个4.使用list()而不是[]得到理解终止于StopIteration抛出的异常next().


Tho*_*mas 5

你的意思是 N个项目,还是N个最大的项目?

如果你想要第一个:

top5 = sequence[:5]
Run Code Online (Sandbox Code Playgroud)

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

如果你想要最大的,并且它没有排序,最明显的解决方案是首先对其进行排序:

l = list(sequence)
l.sort(reverse=True)
top5 = l[:5]
Run Code Online (Sandbox Code Playgroud)

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

import heapq
top5 = heapq.nlargest(5, sequence)
Run Code Online (Sandbox Code Playgroud)

  • `import heapq; top5 = heapq.nlargest(5,iterable)` (4认同)
  • 使用*sequence*而不是*iterable*.一些*iterables*不支持索引.每个*序列*都是*可迭代*,但有些*iterables*不是序列. (2认同)