Reputation: 133
I have a list of letters and want to be able to display them vertically like so:
a d
b e
c f
def main():
letters = ["a", "b", "c", "d","e", "f"]
for i in letters:
print(i)
this code only display them like this:
a
b
c
d
e
Upvotes: 8
Views: 82610
Reputation: 2421
>>> letters = ["a", "b", "c", "d", "e", "f", "g"]
>>> odd_even = zip(letters[::2], letters[1::2] + len(letters) % 2 * [""])
>>> pairs = [" ".join([odd, even]) for odd, even in odd_even]
a b
c d
e f
g
Upvotes: 0
Reputation: 103814
For a general solution, you can do something along these lines:
from itertools import zip_longest
lets = list('abcdefghijklmnop')
def table(it, rows):
return zip_longest(*[it[i:i+rows] for i in range(0, len(it), rows)],
fillvalue=' ')
for t in table(lets, 6):
print(*t)
Prints:
a g m
b h n
c i o
d j p
e k
f l
Since we are using zip_longest (izip_longest
for Python 2), you can supply a fillvalue and the odd ending value will not be truncated.
If you want to change the columns, change the number of rows:
for t in table(lets, 2):
print(*t)
Prints:
a c e g i k m o
b d f h j l n p
Of course, it is easy math to figure out the relationship between cols and rows if you have a list X items long.
So How does this work?
By definition, a table is a matrix. So first, create a matrix that is rows
long:
>>> lets
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p']
>>> rows=6
>>> [lets[i:i+rows] for i in range(0, len(lets), rows)]
[['a', 'b', 'c', 'd', 'e', 'f'], ['g', 'h', 'i', 'j', 'k', 'l'], ['m', 'n', 'o', 'p']]
Then invert that matrix:
>>> for t in zip_longest(*[lets[i:i+rows] for i in range(0, len(lets), rows)]):
... print(t)
...
('a', 'g', 'm')
('b', 'h', 'n')
('c', 'i', 'o')
('d', 'j', 'p')
('e', 'k', None)
('f', 'l', None)
And go from there...
Upvotes: 0
Reputation: 27575
If the goal is to specify the number of COLUMNS in which to display a collections, here's my code
# Python 3
from math import ceil
def pt(x, nbcol):
print ('nbcol ==',nbcol)
y = int(ceil(len(x)/float(nbcol)))
wcol = len(x)//y
if wcol==nbcol or (wcol+1==nbcol and 0 < len(x) - (wcol*y) <= y):
print ('\n'.join('\t'.join(str(el) for el in x[i::y])
for i in range(y)) , '\n' )
else:
print ("I can't do it\n")
li = ['ab','R','uio','b',4578,'h','yu','mlp','AZY12','78']
for nbcol in range(1,9):
pt(li,nbcol)
print ('===============================')
for nbcol in range(1,9):
pt("abcdef",nbcol)
print ('===============================')
for nbcol in range(1,9):
pt('abcdefghijk',nbcol)
example
nbcol == 1
ab
R
uio
b
4578
h
yu
mlp
AZY12
78
nbcol == 2
ab h
R yu
uio mlp
b AZY12
4578 78
nbcol == 3
ab 4578 AZY12
R h 78
uio yu
b mlp
nbcol == 4
ab b yu 78
R 4578 mlp
uio h AZY12
nbcol == 5
ab uio 4578 yu AZY12
R b h mlp 78
nbcol == 6
I can't do it
nbcol == 7
I can't do it
nbcol == 8
I can't do it
===============================
nbcol == 1
a
b
c
d
e
f
nbcol == 2
a d
b e
c f
nbcol == 3
a c e
b d f
nbcol == 4
I can't do it
nbcol == 5
I can't do it
nbcol == 6
a b c d e f
nbcol == 7
I can't do it
nbcol == 8
I can't do it
===============================
nbcol == 1
a
b
c
d
e
f
g
h
i
j
k
nbcol == 2
a g
b h
c i
d j
e k
f
nbcol == 3
a e i
b f j
c g k
d h
nbcol == 4
a d g j
b e h k
c f i
nbcol == 5
I can't do it
nbcol == 6
a c e g i k
b d f h j
nbcol == 7
I can't do it
nbcol == 8
I can't do it
Upvotes: 1
Reputation: 3933
Answer Peter Goldsborough has issue
what about this letters array
>>> letters = ["a", "b", "c", "d","e"]
>>> for n,i in enumerate(letters[:3]):
print(i,letters[n+3])
a d
b e
Traceback (most recent call last):
File "<pyshell#187>", line 2, in <module>
print(i,letters[n+3])
IndexError: list index out of range
I added condition for it
>>> for n,i in enumerate(letters[:3]):
if n + 3 < len(letters):
print(i,letters[n+3])
else:
print(i)
a d
b e
c
The same problem with Paulo Bu's answer.
And here is my I think more simple and universal solution
>>> import math
>>> def main():
letters = ["a", "b", "c", "d", "e", "f"]
rows = 3
columns = int(math.ceil(len(letters) / rows))
for i in range(min(rows, len(letters))):
for j in range(columns):
next_column_i = i + rows * j
if next_column_i < len(letters):
print(letters[next_column_i], end = ' ')
print()
>>> main()
a d
b e
c f
>>>
I can change rows count set it 2 and easy to get this if I need
>>> main()
a c e
b d f
>>>
Upvotes: 1
Reputation: 1388
I'll just throw in another solution:
letters = ["a", "b", "c", "d","e", "f"]
for n,i in enumerate(letters[:3]):
print(i,letters[n+3])
Also outputs:
a d
b e
c f
Upvotes: 4
Reputation: 6053
Without context for what you are doing it is difficult to provide an answer.
If your data need to be in pairs then perhaps you should create a differently structured object. A simple example would be a list of tuples.
def main():
letters = [("a", "d"), ("b", "e"), ("c", "f")]
for pair in letters:
print("%s %s" % pair)
Upvotes: 0
Reputation: 29794
That's because you're printing them in separate lines. Although you haven't given us enough info on how actually you want to print them, I can infer that you want the first half on the first column and the second half on the second colum.
Well, that is not that easy, you need to think ahead a little and realize that if you calculate the half of the list and keep it: h=len(letters)//2
you can iterate with variable i
through the first half of the list and print in the same line letters[i]
and letters[h+i]
correct? Something like this:
def main():
letters = ["a", "b", "c", "d","e", "f"]
h = len(letters)//2 # integer division in Python 3
for i in range(h):
print(letters[i], letters[h+i])
You can easily generalize it for lists without pair length, but that really depends on what you want to do in that case.
That being said, by using Python you can go further :). Look at this code:
def main():
letters = ["a", "b", "c", "d","e", "f"]
for s1,s2 in zip(letters[:len(letters)//2], letters[len(letters)//2:]): #len(letters)/2 will work with every paired length list
print(s1,s2)
This will output the following in Python 3:
a d
b e
c f
What I just did was form tuples with zip
function grouping the two halves of the list.
For the sake of completeness, if someday your list hasn't a pair length, you can use itertools.zip_longest
which works more or less like zip
but fills with a default value if both iterables aren't of the same size.
Hope this helps!
Upvotes: 9