16

I need to print a 3 x 3 array for a game called TicTackToe.py. I know we can print stuff from a list in a horizontal or vertical way by using

listA=['a','b','c','d','e','f','g','h','i','j']
# VERTICAL PRINTING 
for item in listA:
        print item

Output:

a
b
c

or

# HORIZONTAL  PRINTING
for item in listA:
        print item,

Output:

a b c d e f g h i j

How can I print a mix of both, e.g. printing a 3x3 box like

a b c
d e f
g h i

8 Answers 8

23

You can enumerate the items, and print a newline only every third item:

for index, item in enumerate('abcdefghij', start=1):
    print item,
    if not index % 3:
        print

Output:

a b c
d e f
g h i
j

enumerate starts counting from zero by default, so I set start=1.

As @arekolek comments, if you're using Python 3, or have imported the print function from the future for Python 2, you can specify the line ending all in one go, instead of the two steps above:

for index, item in enumerate('abcdefghij', start=1):
    print(item, end=' ' if index % 3 else '\n')
Sign up to request clarification or add additional context in comments.

6 Comments

Amazing that there are specific "recipes" (as Padraic shows), but I think your path is much better -- because your code is simple and its effect obvious to even a Python novice (that is, without knowledge of (rare?) imports).
This could also be rewritten using the print function as for i, v in enumerate('abcdefghij', 1): print(v, end=' ' if i % 3 else '\n').
You could also avoid start=1 and use '\n' if i%3 == 2 else ' ' or ' ' if i%3 < 2 else '\n'.
@Bakuriu I think that's less comprehensible.
To me they are the same. BTW: I don't see the point of calling list when iterating over that string... Is it just because the OP uses a list?
|
11

You can use the logic from the grouper recipe:

listA=['a','b','c','d','e','f','g','h','i','j']

print("\n".join(map(" ".join, zip(*[iter(listA)] * 3))))
a b c
d e f
g h i

If you don't want to lose elements use izip_longest with an empty string as a fillvalue:

listA=['a','b','c','d','e','f','g','h','i','j']
from itertools import izip_longest

print("\n".join(map(" ".join, izip_longest(*[iter(listA)] * 3,fillvalue=""))))

Which differs in that it keeps the j:

a b c
d e f
g h i
j  

You can put the logic in a function and call it when you want to print, passing in whatever values you want.

from itertools import izip_longest

def print_matrix(m,n, fill):
    print( "\n".join(map(" ".join, izip_longest(*[iter(m)] * n, fillvalue=fill))))

Or without itertools just chunk and join, you can also take a sep arg to use as the delimiter:

def print_matrix(m,n, sep):
    print( "\n".join(map("{}".format(sep).join, (m[i:i+n] for i in range(0, len(m), n)))))

You just need to pass the list and the size for each row:

In [13]: print_matrix(listA, 3, " ")
a b c
d e f
g h i
j

In [14]: print_matrix(listA, 3, ",")
a,b,c
d,e,f
g,h,i
j

In [15]: print_matrix(listA, 4, ",")
a,b,c,d
e,f,g,h
i,j

In [16]: print_matrix(listA, 4, ";")
a;b;c;d
e;f;g;h
i;j

Comments

8

A simple approach would be to use the modulo operator:

listA=['a','b','c','d','e','f','g','h','i','j']

count = 0

for item in listA:
    if not count % 3:
        print
    print item,
    count += 1

As pointed out by Peter Wood, you can use the enumerator operator, to avoid the count variable:

listA=['a','b','c','d','e','f','g','h','i','j']

listB = enumerate(listA)
for item in listB:
    if not item[0] % 3:
        print
    print item[1],

2 Comments

Why not use enumerate to do the counting for you?
That is totally functional but the most awkward use of enumerate I've seen. Also, it's the enumerate function, not the enumerator operator. Your version rhymes better though.
5

An alternative to the two answers given here is to use something that does the formatting for you, like numpy. This is an external dependency you might not want in general, but if you're already storing things in grids/matrices, it can be a logical choice:

from numpy import array
str(array(listA).reshape((3,3)))

Put it in an array, reshape it in your favourite (compatible) shape, and make it a string. Couldn't be more intuitive!

5 Comments

"Couldn't be more intuitive!" Really?
@MadPhysicist syntactically, I don't think so (well, maybe I'm a little hyperbolic). Take a flat array and reshape it: that makes sense to me. If I saw this I would immediately know what it's doing: if I saw Padraic's answer with join->map->join->zip->iter, it would take a second to figure out what we were doing. That answer is awesome, don't get me wrong, but I think this is a good option too :)
@MadPhysicist if you're going by "intuitive in terms of what someone new to python would be familiar with" then it seems like the ones using modulus are about as good as you'll get
I agree about it being a good option. My initial reflex was to mention numpy as well when I saw matrix in the title. However, I don't think that adding numpy into the mix is optimal for a guy just trying to figure out how print works. I also wish beginners didn't have to learn print so early, especially the Python2 statement, but that's another story.
@MadPhysicist that all sounds fair
4

You could use the format method of the string object:

for i in range(3):
    print "{} {} {}".format(*listA[3*i:3*i+3])

Also, instead of multiplying the index by 3 at every iteration, you can just take steps of three elements through the list:

for i in range(0, len(listA), 3):
    print "{} {} {}".format(*listA[i:i+3])

4 Comments

In Python 3: for i in range(0, len(listA), 3): print(*listA[i:i+3])
@arekolek, that would work fine in py2.7 as well. It works the same whether you step every three or multiply by three. I chose the latter, but your syntax does look cleaner.
I was actually thinking about the print function when I included the disclaimer. But of course you could import it from the future. BTW you can feel free to incorporate it into your answer.
@arekolek. I may as well.
1

One method which have not been mentioned: Get the slice of the list mathematically and print by the slice of the list.

In Python 2.x:

listA=['a','b','c','d','e','f','g','h','i','j']
val = (len(listA) + 2) // 3
for i in range(val):
    print(' '.join(listA[i*3:(i+1)*3]))

In Python 3.x:

listA=['a','b','c','d','e','f','g','h','i','j']
val = (len(listA) + 2) // 3
for i in range(val):
    print(*listA[i*3:(i+1)*3], sep=" ")

Comments

0
print ''.join(' '*(n%3!=0)+l+'\n'*(n%3==2) for n,l in enumerate(listA))

a b c
d e f
g h i
j

Python is awesome.

8 Comments

Despite Python being awesome this question is not an obfuscated code tournament
Fine line between "obfuscated" and "beautifully succinct", wouldn't you say?
What's the output?
The output has an extra space at the beginning of each line.
The output now has an extra space at the end of each line
|
0

An easy solution #The end="" will print the values in the same line and the empty print() will make the control move to the immediately next line. #Don't use "\n", for it will create an empty line between the rows!

s = []
for i in range(3):
    s.append(list(map(int, input().split())))
for i in range(3):
    for j in range(3):
        print(s[i][j],"",end="")
    print()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.