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

发布于 2024-10-21 03:32:08 字数 194 浏览 4 评论 0原文

使用 我想

var top5 = array.Take(5);

如何用Python做到这一点?

With I would

var top5 = array.Take(5);

How to do this with Python?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

别把无礼当个性 2024-10-28 03:32:08

对列表进行切片

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)

Slicing a list

top5 = array[:5]
  • To slice a list, there's a simple syntax: array[start:stop:step]
  • You can omit any parameter. These are all valid: array[start:], array[:stop], array[::step]

Slicing a generator

import itertools
top5 = itertools.islice(my_list, 5) # grab the first five elements
  • You can't slice a generator directly in Python. itertools.islice() will wrap an object in a new slicing generator using the syntax itertools.islice(generator, start, stop, step)

  • Remember, slicing a generator will exhaust it partially. If you want to keep the entire generator intact, perhaps turn it into a tuple or list first, like: result = tuple(generator)

简美 2024-10-28 03:32:08
import itertools

top5 = itertools.islice(array, 5)
import itertools

top5 = itertools.islice(array, 5)
蛮可爱 2024-10-28 03:32:08

@Shaikovsky 的回答非常好,但我想澄清几点。

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

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


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

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

生成器:
(x 代表 _, x in zip(范围(n), 记录))

@Shaikovsky's answer is excellent, but I wanted to clarify a couple of points.

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

This is the most simple approach, but throws StopIteration if the generator is prematurely exhausted.


On the other hand, the following approaches return up to n items which is preferable in many circumstances:

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

Generator:
(x for _, x in zip(range(n), records))

酷到爆炸 2024-10-28 03:32:08

按照我的口味,将 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)

In my taste, it's also very concise to combine zip() with xrange(n) (or range(n) in Python3), which works nice on generators as well and seems to be more flexible for changes in general.

# 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)
等待圉鍢 2024-10-28 03:32:08

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

>>> 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 异常上终止下一个()。

The answer for how to do this can be found 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]

Notice that the last call asks for the next 4 when only 2 are remaining. The use of the list() instead of [] is what gets the comprehension to terminate on the StopIteration exception that is thrown by next().

染火枫林 2024-10-28 03:32:08

您是指 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)

Do you mean the first N items, or the N largest items?

If you want the first:

top5 = sequence[:5]

This also works for the largest N items, assuming that your sequence is sorted in descending order. (Your LINQ example seems to assume this as well.)

If you want the largest, and it isn't sorted, the most obvious solution is to sort it first:

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

For a more performant solution, use a min-heap (thanks Thijs):

import heapq
top5 = heapq.nlargest(5, sequence)
慕烟庭风 2024-10-28 03:32:08

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

使用列表理解:

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

否则:

first_n_elements = list(generator)[:n]

其中 n 是您想要获取的元素数量(例如,前五个元素的 n=5)。

With itertools you will obtain another generator object so in most of the cases you will need another step the take the first n elements. There are at least two simpler solutions (a little bit less efficient in terms of performance but very handy) to get the elements ready to use from a generator:

Using list comprehension:

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

Otherwise:

first_n_elements = list(generator)[:n]

Where n is the number of elements you want to take (e.g. n=5 for the first five elements).

梦里寻她 2024-10-28 03:32:08

这应该有效

top5 = array[:5] 

This should work

top5 = array[:5] 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文