Home > Mobile >  making a batches using for loop in python
making a batches using for loop in python

Time:10-26

I did the following code, but did not get the expected output.

a=[1, 2, 3, 4, 5, 5, 6, 7, 78, 8, 9, 9, 0, 0, 8, 6, 5, 4, 3, 4]


def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in range(0, len(lst), n):
        yield lst[i:i   n]
        

def hello():
    s=chunks(a,10)
    print(list(s))

hello()  

#output [[1, 2, 3, 4, 5, 5, 6, 7, 78, 8], [9, 9, 0, 0, 8, 6, 5, 4, 3, 4]]

expected output-:
[1, 2, 3, 4, 5, 5, 6, 7, 78, 8]
---------New line----
[9, 9, 0, 0, 8, 6, 5, 4, 3, 4]

expected out is only possible if I am able to put a return in for loop, which is not possible. I think.

Thanks in advance.

CodePudding user response:

If I understood correctly you want a function chunks that does the following:

a = [1, 2, 3, 4, 5, 5, 6, 7, 78, 8, 9, 9, 0, 0, 8, 6, 5, 4, 3, 4]
print(chunks(a, 10))  # [1, 2, 3, 4, 5, 5, 6, 7, 78, 8]
print(chunks(a, 10))  # [9, 9, 0, 0, 8, 6, 5, 4, 3, 4] 

The rest of the answer is based on that assumption.

TL;DR

It cannot (should not) be done with simple functions, use a generator function next

Long Explanation

To the best of my knowledge you cannot use a simple function for that, basically because you cannot keep state in a function.

You could use the following tricks (at your own peril :)):

from itertools import count

a = [1, 2, 3, 4, 5, 5, 6, 7, 78, 8, 9, 9, 0, 0, 8, 6, 5, 4, 3, 4]


def chunks(lst, n, counter=count()):
    """Yield successive n-sized chunks from lst."""
    i = next(counter) * n
    return lst[i:i   n]


print(chunks(a, 10))
print(chunks(a, 10)) 

Output

[1, 2, 3, 4, 5, 5, 6, 7, 78, 8]
[9, 9, 0, 0, 8, 6, 5, 4, 3, 4]

Note that is generally frowned upon because the argument counter the function chunks is a default mutable argument. Another alternative is to use a closure:

from itertools import count

a = [1, 2, 3, 4, 5, 5, 6, 7, 78, 8, 9, 9, 0, 0, 8, 6, 5, 4, 3, 4]

def chunks_maker():
    counter = count()

    def _chunks(lst, n):
        """Yield successive n-sized chunks from lst."""
        i = next(counter) * n
        return lst[i:i   n]

    return _chunks


chunks = chunks_maker()

batch = 2
for i in range(batch):
    print(chunks(a, 10))

Output (from closure)

[1, 2, 3, 4, 5, 5, 6, 7, 78, 8]
[9, 9, 0, 0, 8, 6, 5, 4, 3, 4]

But, the Zen of Python states:

There should be one-- and preferably only one --obvious way to do it. 

and that way at least in my humble opinion is to use a generator function next.

Other resources on keeping state without classes in Python are:

CodePudding user response:

Variable s in your hello method is a generator object. You can simply iterate over the generator and keep on printing the values in new line.

Try this:

a=[1, 2, 3, 4, 5, 5, 6, 7, 78, 8, 9, 9, 0, 0, 8, 6, 5, 4, 3, 4]


def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in range(0, len(lst), n):
        yield lst[i:i   n]
        

def hello():
    s=chunks(a,10)
    for l in s:
        print(l)

hello() 

Output:

[1, 2, 3, 4, 5, 5, 6, 7, 78, 8]
[9, 9, 0, 0, 8, 6, 5, 4, 3, 4]

CodePudding user response:

Use next() method for getting elements of generator one by one.

a=[1, 2, 3, 4, 5, 5, 6, 7, 78, 8, 9, 9, 0, 0, 8, 6, 5, 4, 3, 4]


def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in range(0, len(lst), n):
        yield lst[i:i   n]
        

def hello():
    s=chunks(a,10)
    # s is a generator object
    # to print the chunk use next method
    print(next(s))
    print(next(s))

hello()

Output

[1, 2, 3, 4, 5, 5, 6, 7, 78, 8]
[9, 9, 0, 0, 8, 6, 5, 4, 3, 4]
  • Related