Home > Back-end >  What is a nice, python style way to yield ranged subsets of a string/bytes/list several items at a t
What is a nice, python style way to yield ranged subsets of a string/bytes/list several items at a t

Time:12-12

I want to loop over bytes data, and I'd hope the same principle would apply to strings and lists, where I don't go item by item, but a few items at a time. I know I can do mystr[0:5] to get the first five characters, and I'd like to do that in a loop.

I can do it the C style way, looping over ranges and then returning the remaining elements, if any:

import math
def chunkify(listorstr, chunksize:int):
    # Loop until the last chunk that is still chunksize long
    end_index = int(math.floor(len(listorstr)/chunksize))
    for i in range(0, end_index):
        print(f"yield ")
        yield listorstr[i*chunksize:(i 1)*chunksize]
    # If anything remains at the end, yield the rest
    remainder = len(listorstr)%chunksize
    if remainder != 0:
        yield listorstr[end_index*chunksize:len(listorstr)]
        
[i for i in chunkify("123456789", 2)]

This works just fine, but I strongly suspect python language features could make this a lot more compact.

CodePudding user response:

You can condense your code using the range step parameter. Instead of the for loop, a generator for this is

listorstr[i:i chunksize] for i in range(0,len(listorstr), chunksize)

Your function could yield from this generator to make for a more tidy call.

def chunkify(listorstr, chunksize:int):
    yield from (listorstr[i:i chunksize] 
        for i in range(0,len(listorstr), chunksize))
  • Related