在一次生成器上一次迭代N个项目

时间:2018-08-22 14:38:33

标签: python-3.x

我该怎么做? islice()一次返回n个项目,但我不知道如何进行迭代。 现在我做这样的事情:

# -*- coding: utf-8 -*-
'''
   print 3 lines at a time.
'''

def myread(filename):
  with open(filename,'r',encoding='utf-8-sig') as f:
    for line in f:
        yield line.strip()

filename = 'test.txt'
temp = []
for res_a in myread(filename):
  temp.append(res_a)
  if len(temp)==3:
    print(temp)
    temp = []
print(temp)

请注意,我不知道我的文本文件有多大。

2 个答案:

答案 0 :(得分:2)

您可以使用itertools.isliceiter的两个参数形式,例如:

from itertools import islice

with open('file') as fin:
    # gen-comp yielding stripped lines
    lines = (line.strip() for line in fin)
    # create list of at most 3 lines from the file's current position 
    # and use an empty list as a sentinel value of when to stop... (no more lines)
    for three in iter(lambda: list(islice(lines, 3)), []):
        print(three)

功能:

def myread(filename): 
    with open(filename) as fin:
        lines = (line.strip() for line in fin)
        yield from iter(lambda: list(islice(lines, 3)), [])

答案 1 :(得分:1)

islice(itr, n)将仅返回运行直到到达n的第itr个元素的迭代器。您将不得不继续为要返回的每组islice元素重建n迭代器。您可能要尝试使用the itertools documentation中的grouper配方,这样可以避免这种重建:

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

要完成该示例,您可以过滤掉添加到输出组的fillvalue,以使其复制OP提供的代码:

for grp in grouper(myread(filename), 3):
    trimmed_grp = [line for line in grp if line is not None]
    print(trimmed_grp)