How can I convert a python tuple to a two dimensional table?
Here's a short version in case you find the rest of this too verbose:
n = 9
table = zip(*[iter(data)]*n)
Let's say you start with a list:
>>> data = range(1,101)
>>> data
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
99, 100]
Create an iterator for your list:
>>> data_iter = iter(data)
Now use a function zip
to split the list. Note, this is the fun part!
>>> table = zip(*[data_iter]*9)
>>> pprint.pprint(table)
[(1, 2, 3, 4, 5, 6, 7, 8, 9),
(10, 11, 12, 13, 14, 15, 16, 17, 18),
(19, 20, 21, 22, 23, 24, 25, 26, 27),
(28, 29, 30, 31, 32, 33, 34, 35, 36),
(37, 38, 39, 40, 41, 42, 43, 44, 45),
(46, 47, 48, 49, 50, 51, 52, 53, 54),
(55, 56, 57, 58, 59, 60, 61, 62, 63),
(64, 65, 66, 67, 68, 69, 70, 71, 72),
(73, 74, 75, 76, 77, 78, 79, 80, 81),
(82, 83, 84, 85, 86, 87, 88, 89, 90),
(91, 92, 93, 94, 95, 96, 97, 98, 99)]
The expression `[data_iter] * 9 'results in the following list:
[ data_iter, data_iter, data_iter, data_iter, data_iter, data_iter, data_iter, data_iter, data_iter ]
The expression *[data_iter]*9
turns this into nine arguments to a zip
function. This function zip
creates a list of tuples:
Returns a list of tuples, where each tuple contains the ith element from each of the argument sequences. The returned list is truncated to the length of the shortest sequence of arguments.
Since we are using an iterator, each time the function zip
looks for a new value, it gets the next value in the sequence. Compare this to the behavior if we were just using a list in the same way:
>>> table = zip(*[data]*9)
>>> pprint.pprint(table)
[(1, 1, 1, 1, 1, 1, 1, 1, 1),
(2, 2, 2, 2, 2, 2, 2, 2, 2),
(3, 3, 3, 3, 3, 3, 3, 3, 3),
...
(99, 99, 99, 99, 99, 99, 99, 99, 99),
(100, 100, 100, 100, 100, 100, 100, 100, 100)]
UPDATE . A colleague of mine points out that if you have NumPy, you can do the following:
>>> data = numpy.array(range(1,101))
>>> data.reshape([10,10])
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
[ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
[ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
[ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
[ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60],
[ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70],
[ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80],
[ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90],
[ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]])
source to share
I'm surprised it's not in itertools
, but it doesn't seem to be. Here's my approach:
def segment_list(lst, step):
"""
Segment lst into a list of step-length lists
"""
segments = []
while True:
if len(lst) <= step:
output.append(lst)
break
output.append(lst[0:step])
lst = lst[step+1:]
return segments
source to share
>>> n = 3
>>> data = ('a', 'b', 'c', 'd', 'e', 'f',
... 'g', 'h', 'i', 'j', 'k', 'l',
... 'm', 'n')
>>> table = []
>>> for i in xrange( 0, divmod( len(data), n)[0] + 1):
... table.append( data[i*n:i*n+n] )
>>> print tuple( table )
(('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i'), ('j', 'k', 'l'), ('m', 'n'))
source to share