简体   繁体   中英

Iterate N items at a time on a generator with single yield

How do I do that? islice() return n items at a time but I can't figure out how to iterate it. Right now I do something like this:

# -*- 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)

Note that I don't know how big is my text file.

You can use itertools.islice and the two argument form of iter , eg:

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)

As a function:

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

islice(itr, n) will only return an iterator that runs until it reaches the n th element of itr . You would have to keep rebuilding the islice iterator for every group of n elements you want to return. You might want to try the grouper recipe from the itertools documentation , which avoids this rebuilding:

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)

To complete the example, you can filter out the fillvalue s added to the output groups to get it to replicate the code provided by the OP:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM