14

I have a list of unknown number of items, let's say 26. let's say

list=['a','b','c','d','e','f','g','h',
'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']

How to print like this:

abcde

fghij

klmno

pqrst

uvwxy

z

? Thank you very much. Attempt:

    start = 0
    for item in list:
        if start < 5:
            thefile.write("%s" % item)
            start = start + 5
        else:
            thefile.write("%s" % item)
            start = 0
svick
  • 236,525
  • 50
  • 385
  • 514
Ka Wa Yip
  • 2,546
  • 3
  • 22
  • 35
  • 2
    Hi kw yip. I think you are doing a pretty good job, except for the start = start + 5 line. You are writting *one* item and skipping the next four, which is not what you want. You have a couple of good answers below, so I will not add another one, but also think about using "{0}.format(item)" instead of the old syntax "%s" % item. – Jblasco May 26 '15 at 06:50
  • and you also need to add break line. i.e. on your `else` section. write `"%s\n"` instead of `"%s"` – Elisha May 26 '15 at 07:23
  • Some answers don't produce the exact result you gave in your example. Namely, an empty line between each printed line or no space between elements in each line. Some of those answers can be tweaked easily to produce the exact result, but others can't. Can you state whether the format of the printed result is important or just the concept of printing X items per line? – Reti43 May 26 '15 at 15:12
  • it's just the concept of printing (actually writing to a txt file). Thanks. – Ka Wa Yip May 26 '15 at 17:14
  • See also [How to print X items in a list per line](https://stackoverflow.com/q/22753175/7851470) for a simpler case without joining strings and without empty lines. – Georgy May 31 '20 at 15:43

12 Answers12

21
for i, a in enumerate(A):
    print a, 
    if i % 5 == 4: 
        print "\n"

Another alternative, the comma after the print means there is no newline character

dabhand
  • 517
  • 3
  • 10
  • While the comma after print is a good trick to know, in this case you're using 6 print statements for every 5 elements when you can use only one by slicing the array. It shouldn't matter for a few items but keep in mind printing is slow. – Reti43 May 26 '15 at 11:24
  • +1. Only answer using modulus, which IMO is the cleanest, if not best, way to go about these kind of questions. – user1021726 May 26 '15 at 14:00
  • @Reti43: You don't think that slicing and joining an array as the (current) top answer is doing is more costly than just printing? – user1021726 May 26 '15 at 14:02
  • @user1021726 Slicing and joining arrays is cheaper than repeated one-character print statements. You can do a timing test on this, printing is terribly slow in Python. I used the timeit library. python -m timeit -s "import string" -s "lst = list(string.ascii_lowercase)" "for i,a in enumarate(lst):" " print a," " if i%5 == 4: print '\n'" - this results in 2.58 milliseconds per loop, while doing the same setup and using anmol_uppal's code results in 360 microseconds. That's a massive improvement that cuts down running time to ~14% – Mateon1 May 26 '15 at 15:01
  • Printing is definitely slow & in production code I would use a joint / slice approach, I thought this is a very clear way though. – dabhand Jun 22 '15 at 15:29
15

You can simple do this by list comprehension: "\n".join(["".join(lst[i:i+5]) for i in xrange(0,len(lst),5)]) the xrange(start, end, interval) here would give a list of integers which are equally spaced at a distance of 5, then we slice the given list in to small chunks each with length of 5 by using list slicing.

Then the .join() method does what the name suggests, it joins the elements of the list by placing the given character and returns a string.

lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

print "\n".join(["".join(lst[i:i+5]) for i in xrange(0,len(lst),5)])

>>> abcde
    fghij
    klmno
    pqrst
    uvwxy
    z
ZdaR
  • 22,343
  • 7
  • 66
  • 87
  • This is a good (short & fast) solution if you're working on lists which fit in RAM, but if you're working on an iterable like a file which does not fit into RAM you might to use this [iterator based approach](http://stackoverflow.com/a/30533904/1423333) – Jörn Hees May 29 '15 at 16:06
9

It needs to invoke for-loop and join functions can solve it.

l=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']

for i in range(len(l)/5+1):
    print "".join(l[i*5:(i+1)*5]) + "\n"

Demo:

abcde

fghij

klmno

pqrst

uvwxy

z
Burger King
  • 2,945
  • 3
  • 20
  • 45
6

Lots of answers here saying you how to do it, but none explaining how to figure it out. The trick I like to use to figure out a loop is to write the first few iterations by hand, and then look for a pattern. Also, ignore edge cases at first. Here, the obvious edge case is: what if the size of the list is not a multiple of 5? Don't worry about it! I'm going to try to avoid using any fancy language features that would make things easier for us in this answer, and instead do everything manually, the hard way. That way we can focus on the basic idea instead of cool Python features. (Python has lots of cool features. I'm honestly not sure if I can resist them, but I'll try.) I'm going to use print statements instead of thefile.write, because I think it's easier to read. You can even use print statements to write to files: print >> thefile, l[0], and no need for all those %s strings :) Here's version 0:

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

This loop is simple enough that two iterations is probably enough, but sometimes you may need more. Here's version 1 (note that we still assume the size of the list is a multiple of 5):

idx=0
while idx < len(l):
  print l[idx], l[idx+1], l[idx+2], l[idx+3], l[idx+4]
  a += 5

Finally, we're ready to take care of the annoying fact that most numbers are not a multiple of 5. The above code will basically crash in that case. Let's try to fix it without thinking too hard. There are several ways to do this; this is the one I came up with; you're encouraged to try to come up with your own before peeking at what I did. (Or after peeking if you prefer.) Version 2:

idx=0
while idx < len(l):
  print l[index],
  if idx+1 < len(l): print l[idx+1],
  if idx+2 < len(l): print l[idx+2],
  if idx+3 < len(l): print l[idx+3],
  if idx+4 < len(l): print l[idx+4]
  idx += 5

We finally have code that does what we want, but it's not pretty. It's so repetitive that I resorted to copy/paste to write it, and it's not very symmetric either. But we know what to do about repetitive code: use a loop! Version 3:

idx=0
while idx < len(l):
  b = 0
  while b < 5:
    if idx+b < len(l): print l[idx+b],
    b += 1
  print
  idx += 5

It's no longer repetitive, but it didn't get any shorter. This might be a good time to look at our code and see if it reflects the best solution, or merely reflects the path we took to get here. Maybe there is a simpler way. Indeed, why are we processing things in blocks of five? How about we go one at a time, but treat every fifth item specially. Let's start over. Version 4:

idx=0
while idx < len(l):
  print l[idx],
  if idx % 5 == 4: print
  idx += 1

Now that's much prettier! At this point, we've worked hard, and reward ourselves by looking at what cool features Python has to make this code even nicer. And we find that dabhand's answer is almost exactly what we have, except that it uses enumerate so Python does the work of keeping track of what number we're on. It only saves us two lines, but with such a short loop, it almost cuts our line count in half :) Version 5:

for idx, item in enumerate(l):
  print item,
  if idx % 5 == 4: print

And that's my final version. Many people here suggest using join. It's a good idea for this problem, and you might as well use it. The trouble is it would not help if you had a different problem. The DIY approach works even when Python does not have a pre-cooked solution :)

Mark VY
  • 1,489
  • 16
  • 31
  • This does not produce the output expected by the OP: there will be blanks between the letters – WoJ May 26 '15 at 12:03
  • 1
    True, but based on the wording of the question, I don't think the goal is to print letters; that was just an example. The OP already knows how to use file.write if needed; my goal was to explain how to write the loop. – Mark VY May 26 '15 at 12:57
4

This will work:

n = m = 0
while m < len(l):
    m = m+5
    print("".join(l[n:m]))
    n = m

But I believe there is a more pythonic way to accomplish the task.

Liam
  • 6,009
  • 4
  • 39
  • 53
fiacre
  • 1,150
  • 2
  • 9
  • 26
4

You can something easier like below , break your list into sub-list , also this seems more Pythonic . Then print it how ever u want . Also don't use list as it's a keyword(not recommended)

sub_list1=[list1[x:x+5] for x in xrange(0, len(list1), 5)]
for each in sub_list1:
    print( ''.join(each))
coder3521
  • 2,608
  • 1
  • 28
  • 50
3
start = 0
for item in list:
    if start < 4:
        thefile.write("%s" % item)
        start = start + 1
    else:                             #once the program wrote 4 items, write the 5th item and two linebreaks
        thefile.write("%s\n\n" % item)
        start = 0
moffeltje
  • 4,521
  • 4
  • 33
  • 57
  • This code is invalid since it increments the "start" by 4 after printing each item. It prints 3 characters on each line, not 5. – Mateon1 May 26 '15 at 15:05
3
for x in range(0, len(list), 5):
        print(*list[x:x+5])

The idea here is to count by 5 (starting at 0), and then slice out the item that's indexed at that count and the next 4 items.

Count Slice
0 0 - 4
5 5 - 9
10 10 - 14
boner
  • 49
  • 4
2

Just to prove I am really an unreformed JAPH regular expressions are the way to go!

import re
q="".join(lst)
for x in re.finditer('.{,5}',q)
  print x.group()
Vorsprung
  • 32,923
  • 5
  • 39
  • 63
2

Python 3+ simple way

lst=['a','b','c','d','e','f','g','h','i','j','k','l','m',
     'n','o','p','q','r','s','t','u','v','w','x','y','z']

for ind, smb in enumerate(lst):
    print(smb, end='')
    if ind%5 == 4: 
        print('\n')
Plo_Koon
  • 2,953
  • 3
  • 34
  • 41
2

I think the most cleaner way to write this would be

list=['a','b','c','d','e','f','g','h', 'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']

for i in range(0, len(list), 5):
    print(*list[i:i+5], sep='')
1

If you're working on an iterable (like a file) which is potentially too big to fit in RAM you can use something like this:

from itertools import izip_longest
def chunker(iterable, n, fillvalue=None):
    """Like an itertools.grouper but None values are excluded.

    >>> list(chunker([1, 2, 3, 4, 5], 3))
    [[1, 2, 3], [4, 5]]
    """
    if n < 1:
        raise ValueError("can't chunk by n=%d" % n)
    args = [iter(iterable)] * n
    return (
        [e for e in t if e is not None]
        for t in izip_longest(*args, fillvalue=fillvalue)
    )

with open('some_file') as f:
    for row in chunker(f, 5):
        print "".join(row)

If RAM is not a consideration the answer by ZdaR is preferable as it is considerably faster.

Community
  • 1
  • 1
Jörn Hees
  • 3,338
  • 22
  • 44