rotating a table representation

32 views
Skip to first unread message

Chad MILLER

unread,
May 19, 2009, 5:37:55 AM5/19/09
to orlan...@googlegroups.com
By "table", I mean an array of equal-sized arrays, which represent a rectangular table.  Think of the rectangle sliced vertically, so the data is a list of columns, each of which is a list of items down.  We want to change it to being sliced horizontally, so the data is a list of rows, each of which is a list of items across.

1 2 3 4
5 6 7 8

>>> t = [[1,5], [2,6], [3,7], [4,8]]

Now, make it

[[1,2,3,4], [5,6,7,8]]

One can do this by exploiting Python's parameter expansion, and by using a builtin function.

----

First, about parameter expansion.

In Python function definitions, one can catch variable arguments by declaring the multiple-value catcher with an asterisk (and keyword parameters into a dictionary with two asterisks).

>>> def print_items(*params):
        ...

When one calls this with  print_items(1,2,3,'four') , params will be a tuple that contains those values, (1,2,3,'four') .

The reverse is also true, in that one can use an iterable in a function call, with an asterisk, to fill the values.

>>> x = (1,2,3)
>>> def f(a,b,c):
        print b
>>> f(*x)   # prints 2

You can also catch some in normal parameters first.

>>> def f(a, *j):
       print j[0]
>>> f(*x)   # prints 2

----

So, we have a list of lists.  The builtin  zip  function takes any number of iterables and returns a new list, of the first of each in a tuple, then the second of each in a tuple, then third ...  until any given parameter is exhausted*.

>>> zip("chad", "miller")
[('c', 'm'), ('h', 'i'), ('a', 'l'), ('d', 'l')]

Now, we know that we can fill those parameters automatically from an iterable by using an asterisk.

So, rotating a table is as easy as:

>>> t = [[1,5], [2,6], [3,7], [4,8]]
>>> zip(*t)
[(1, 2, 3, 4), (5, 6, 7, 8)]

Of course, that  zip  is exactly like calliing it with the four parameters
>>> zip([1,5], [2,6], [3,7], [4,8])

----

So, this explores variable argument function calls and function definitions.  We didn't explore named parameters, but you can be assured that they are similar, except stored in or retreived from a dictionary using two asterisks, as in  **dictionary .

Happy hacking,

- chad


*  If you don't like that zip aborts at exhausion of any iterable, and you want to rotate something that is not rectangular, you can use  map() .  There is a special case for the callable that's supposed to be in the first parameter.  If you use  None , it acts like zip, but padding all short lists with  None .
>>> map(None, "chad", "miller")
[('c', 'm'), ('h', 'i'), ('a', 'l'), ('d', 'l'), (None, 'e'), (None, 'r')]
Reply all
Reply to author
Forward
0 new messages