1

I'm using Python3. I want to get 4 items from mylist to populate list2 and print my list2 every 4 loops. And I need to print the rest even if there are just 1, 2 or 3 items at the end.

I want to do this with mod % :

mylist = [1, 2, 3, 4, 5]
list2 = []
for count, el in enumerate(mylist):
    list2.append(el)
    if count % 4 == 0:
        print(list2)
        list2 = []

Output :

[1]
[2, 3, 4, 5]

But I need the inverse.

I tried to start at 1 enumerate(mylist, 1): but the output is [1, 2, 3, 4] the last is ignored.

The output that I need is :

[1, 2, 3, 4]
[5]

The length of mylist is totally random. How can I do to get the output that I want ?

John
  • 4,711
  • 9
  • 51
  • 101
  • Possible duplicate of [How do you split a list into evenly sized chunks?](https://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks) – Christian Sloper Oct 23 '18 at 11:59

4 Answers4

2

count starts at 0, and 0%4==0.

So just use the enumerate as you did and then at the end

if len(list2) != 0
    print(list2)
Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62
2

You have two problems. One is the start at 0, as you noticed. The second is that you only print if the list has exactly 4 elements, so if there is something left at the end, then there is no print call anymore after the loop that prints those remaining values. Add it at the end:

mylist = [1, 2, 3, 4, 5]
list2 = []
for count, el in enumerate(mylist, 1):
    list2.append(el)
    if count % 4 == 0:
        print(list2)
        list2 = []

if list2: print(list2)
RemcoGerlich
  • 30,470
  • 6
  • 61
  • 79
1

@remcogerlich wrote a good answer for what you're asking for. Although, I'd recommend not using % 4 for what you're achieving (until its some kind of homework from school) and use list slicing instead:

n = 4
for i in range(0, len(mylist), n):
    print(mylist[i:i + n])

Python can handle index "overflow" so you can write more high-level code instead of caring about tail size. Take a look at similar old question

Slam
  • 8,112
  • 1
  • 36
  • 44
  • I don't need to just print a list it's just an example for SO. I need a `if` statement to accomplish what I want in this case. You seem to not appreciate modulo, does this operator isn't optimized ? – John Oct 23 '18 at 12:10
  • It is optimised and I appreciate it. The issue is that a lot of times people asking about "how to implement my idea" instead of "how to solve my problem". Both is fine, but that later is ten times more rewarding in terms of learning. It's not quite obvious what you're trying to achieve if you're doing fine-grained control over list indices. If you need sub-lists — slicing is more "pythonic", if you juggle indices — you need `range`. Re-allocating & appending helper list is not optimal in a lot of cases – Slam Oct 23 '18 at 12:15
  • Of course each time I take the better answer even it's totally different from my idea. But I was thinking that is good to use mod here because I need to do something ever 4 loops. I didn't know the way how you do the loop with range. But if you say it's better that modulo I take your answer – John Oct 23 '18 at 12:22
  • That's actually good example of what I mean — if you're using python, try thinking with a bit higher-level abstractions (tbh, it rarely comes easy). This is a big part of python, actually. I.e. instead of "loop over list, every 4 loop make ..." think if "make ... with every 4 elements". Its hard to generalize, but 95% if you're juggling list indices inside `for` loop — there should be better way. – Slam Oct 23 '18 at 12:26
  • Yep I understand. I'm not really good with python I do basic things. That is why I ask lot of questions about python to learn the best way – John Oct 23 '18 at 12:31
1

Sounds to me you just want to chunk the data into groups of 4. This is done best here:

How do you split a list into evenly sized chunks?

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

for i in chunks(mylist,4):
    print(i)
Christian Sloper
  • 7,440
  • 3
  • 15
  • 28