开发者

How to convert python tuple into a two dimentional table?

开发者 https://www.devze.com 2023-04-03 04:28 出处:网络
a flat (one dimension) tuple on input: data = (\'a\',\'b\',\'c\'.....\'z\'); output: table开发者_开发技巧 (two dimensions) that has n (say 9) columns

a flat (one dimension) tuple on input:

data = ('a','b','c'.....'z');

output: table开发者_开发技巧 (two dimensions) that has n (say 9) columns

table = ?what code here?

so

print table
 ( ('a','b','c'...), ('k','l','m','n'...), ....)

which is the shortest way to do so?


Here's the short version if you find the rest of this too wordy:

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 the zip function to split up the list. Pay attention, 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 expresion *[data_iter]*9 turns this into nine arguments to the zip function. This zip function builds a list of tuples:

Return a list of tuples, where each tuple contains the i-th element from each of the argument sequences. The returned list is truncated in length to the length of the shortest argument sequence.

Because we're using an iterator, every time zip function looks for a new value it gets the next value in the sequence. Contrast this with the behavior if we had simply used a list 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: My colleague points out that if you have NumPy available, you can do this:

>>> 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]])


How about this:

table = tuple(data[n:n+9] for n in xrange(0,len(data),9))

Returns a tuple made from stepping through data 9 items at a time. If you want to change the number of columns, just change both nines in the generator


I'm surprised this isn't 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


>>> 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'))


Daenth,

The zip method described by larsks (above) is described in the itertools module documentation - search for "grouper" among the recipes:

  • http://docs.python.org/library/itertools.html#recipes
0

精彩评论

暂无评论...
验证码 换一张
取 消