我想循环一个迭代器的“片段”。我不确定这是否可能,因为我知道不可能分割迭代器。我想做的是:
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有没有一种节奏式的方法来循环通过一个发电机的“部分”?
基本上,我所关心的生成器读取一个非常大的文件,并逐行对其执行一些操作。我想测试文件的切片,以确保事情按预期执行,但让它运行整个文件是非常耗时的。
编辑:
如前所述,我需要把这个写在一个文件上。我希望有一种方法可以在生成器中显式地指定这一点,例如:
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上面的代码完成了我所需要的,但是仍然非常慢,因为生成器仍然遍历所有的行。我希望只在指定的切片上循环
发布于 2016-01-11 23:07:35
通常是itertools.islice,但是您应该注意到,islice实际上没有跳过值,也不能跳过值。它只是在启动start -ing值之前抓取并丢弃yield值。因此,如果可能的话,最好避免使用islice,因为需要跳过许多值和/或被跳过的值获取/计算成本很高。如果您能够找到一种方法来不首先生成这些值,那么就这样做。在您(显然是人为的)示例中,您只需调整range对象的开始索引。
在试图在文件对象上运行的特定情况下,拉出大量行(特别是从慢速介质中读取)可能并不理想。假设您不需要特定的行,您可以使用一个技巧来避免实际读取文件的巨大块,同时仍然测试文件的一些距离,那就是seek到一个猜测的偏移量,读出到行的末尾(放弃您可能在中间查找的部分行),然后从那个点开始删除您想要的行数。例如:
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文档和/或数据格式,以确定如何正确地跳过。看起来像, but that's still going to read if not process most of the file。如果数据是以相同的序列长度写出的,我会查看Alignment上的文档;对齐的数据可以通过e.g s that skip the rest of the data for you加载而不需要处理前面的数据。
发布于 2016-01-11 22:46:09
孤岛是节奏曲的方式
from itertools import islice
g = (i for i in range(100))
for num in islice(g, 95, None):
print num发布于 2016-01-11 22:59:58
不能使用普通的slice operations对生成器对象或迭代器进行切片。相反,您需要使用itertools.islice作为@jonrsharpe在他的comment中已经提到。
import itertools
for i in itertools.islice(x, 95)
print(i)还请注意,islice返回迭代器并使用迭代器或生成器上的数据。因此,如果需要返回并执行某些操作或使用鲜为人知的itertools.tee来创建生成器的副本,则需要将数据转换为列表或创建新的生成器对象。
from itertools import tee
first, second = tee(f())https://stackoverflow.com/questions/34732311
复制相似问题