当前位置: 首页 > 面试题库 >

如何切片生成器对象或迭代器?

谭越
2023-03-14
问题内容

我想遍历一个迭代器的“切片”。我不确定这样做是否可行,因为据我了解,无法切片迭代器。我想做的是这样的:

def f():
    for i in range(100):
        yield(i)
x = f()

for i in x[95:]:
    print(i)

这当然会失败:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-37-15f166d16ed2> in <module>()
  4 x = f()
  5 
----> 6 for i in x[95:]:
  7     print(i)

TypeError: 'generator' object is not subscriptable

有没有一种pythonic的方法可以循环通过生成器的“切片”?

基本上,我实际上关心的生成器读取一个很大的文件,并逐行对其执行一些操作。我想测试文件的片段以确保一切正常,但是让它在整个文件上运行非常耗时。

编辑:
如前所述,我需要在文件上执行此操作。我希望有一种方法可以例如使用生成器显式指定:

import skbio

f = 'seqs.fna'
seqs = skbio.io.read(f, format='fasta')

seqs是一个生成器对象

for seq in itertools.islice(seqs, 30516420, 30516432):
    #do a bunch of stuff here
    pass

上面的代码满足了我的需要,但是由于生成器仍然循环遍历所有行,所以它仍然很慢。我希望只循环遍历指定的切片


问题答案:

通常,答案是itertools.islice,但是您应该注意islice,实际上也不会,也不会跳过值。它只是start在开始给yield值赋值之前捕获并丢弃值。因此,通常最好避免islice在可能的情况下需要跳过很多值和/或被跳过的值获取/计算成本很高。如果可以找到一种方法,首先不要生成这些值。在您的(显然是人为的)示例中,您只需调整range对象的起始索引。

在尝试在文件对象上运行的特定情况下,拉很多行(尤其是从慢速介质读取)可能不是理想的选择。假设您不需要特定的行,可以使用一种技巧来避免实际读取文件的大块,同时仍然测试到文件的一定距离,即seek猜测到的偏移量,读出到行的末尾(舍弃您可能会寻找到的中间部分线),然后islice从该点开始关闭任何想要的线。例如:

import itertools

with open('myhugefile') as f:
    # Assuming roughly 80 characters per line, this seeks to somewhere roughly
    # around the 100,000th line without reading in the data preceding it
    f.seek(80 * 100000)
    next(f)  # Throw away the partial line you probably landed in the middle of
    for line in itertools.islice(f, 100):  # Process 100 lines
        # Do stuff with each line

对于文件的特定情况,您可能还希望查看mmap可以以类似方式使用的文件(如果您正在处理数据块而不是文本行,并且在处理过程中可能会随机跳动,这将非常有用)。

更新:
从更新后的问题中,您需要查看您的API文档和/或数据格式,以弄清楚如何正确跳过。似乎skbio提供了一些跳过使用的功能seq_num,但是如果不处理大部分文件,仍然可以读取。如果以相等的序列长度写出数据,我将查看Alignment;上的文档。对齐的数据可能是完全可以加载的,而无需处理之前的数据,例如,通过使用Alignment.subalignment来创建新Alignment的,从而为您跳过其余数据。



 类似资料:
  • 问题 你想得到一个由迭代器生成的切片对象,但是标准切片操作并不能做到。 解决方案 函数 itertools.islice() 正好适用于在迭代器和生成器上做切片操作。比如: >>> def count(n): ... while True: ... yield n ... n += 1 ... >>> c = count(0) >>> c[10:20] Tr

  • 本文向大家介绍python生成器,可迭代对象,迭代器区别和联系,包括了python生成器,可迭代对象,迭代器区别和联系的使用技巧和注意事项,需要的朋友参考一下 生成器,可迭代对象,迭代器之间究竟是什么关系? 用一幅图来概括: 1.生成器 定义生成器 方式一: 方式二: 定义成功后,我们可以利用next()访问生成器下一个元素 但一般用for循环遍历 2.迭代器 任何实现了__iter__和__ne

  • 生成器迭代 手动迭代生成器,递归执行 AsyncTask::next,调用Generator::send方法将将yield值作为yield表达式结果。 yield表达式可能是一个异步调用,我们这里为之后把异步调用的结果作为yield表达式结果铺垫。 yield外侧括号在PHP5必须,PHP7不需要。 如, $ip = (yield async_dns_lookup(...) ); ^

  • 本文向大家介绍简述 生成器、迭代器、可迭代对象 以及应用场景?相关面试题,主要包含被问及简述 生成器、迭代器、可迭代对象 以及应用场景?时的应答技巧和注意事项,需要的朋友参考一下 迭代器 含有iter和next方法 (包含next方法的可迭代对象就是迭代器) 生成器: 包括含有yield这个关键字,生成器也是迭代器,调动next把函数变成迭代器。     可迭代对象 一个类内部实现iter方法且返

  • 这篇内容挺多的,而且比内容不好理解。或许新手看完后,还会一脸懵逼,不过这是正常的,如果你看完后,是迷糊的,那么建议你继续学习后面的内容,等学完,再回来看几次。 注:这也是我第二次修改内容没有改过的章节。 目录

  • 本文向大家介绍Python进阶之迭代器与迭代器切片教程,包括了Python进阶之迭代器与迭代器切片教程的使用技巧和注意事项,需要的朋友参考一下 在前两篇关于 Python 切片的文章中,我们学习了切片的基础用法、高级用法、使用误区,以及自定义对象如何实现切片用法(相关链接见文末)。本文是切片系列的第三篇,主要内容是迭代器切片。 迭代器是 Python 中独特的一种高级特性,而切片也是一种高级特性,