[Tutor] Transposing [n, [e],[s[te]],[d]] sequences

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Mon, 18 Feb 2002 20:12:21 -0800 (PST)


On Sun, 17 Feb 2002, kevin parks wrote:

> # Problem: how do i make something like this work for nested 
> # sequences? since sometimes we will have lists of lists or (god help 
> # us) list of *gasp* tuples...
> 
> 
> By this i meant not first flattening the list or returning the list as
> flat, but transposing each element leaving the structure in place.

Well, one thing we can do is cheat.

###
>>> import re
>>> number_re = re.compile(r'[0-9]+')
>>> l = [[0, 2], 4, [[[5], 7], 9], 11]
>>> number_re.sub(str(l), '%s')
'%s'
>>> number_re.sub('%s', str(l))
'[[%s, %s], %s, [[[%s], %s], %s], %s]'
>>> number_re.sub('%s', str(l)) % (4, 6, 8, 9, 11, 1, 3)
'[[4, 6], 8, [[[9], 11], 1], 3]'
>>> eval(number_re.sub('%s', str(l)) % (4, 6, 8, 9, 11, 1, 3))      
[[4, 6], 8, [[[9], 11], 1], 3]
###


But perhaps this is not what you're looking for.  *grin*

I don't meant to be flippant; I'm still trying to think of a good clean
way of doing this, but for a quick and dirty way, the above might be
useful.


I know that to apply a function "deeply" into a list, we can use
recursion.  The idea behind the recursion is:

    1.  To apply a function deeply on a list, apply a function deeply on
        each element of that list and just collect the
        results.  (Inductive case)

    2.  Trying to apply a function deeply on a nonlist is a dead end ---
        let's just apply the function.  (Base case)

Here's a function that tries to capture this idea of a deep list
transform:

###
>>> def deepTransform(some_function, some_thing):
...     if type(some_thing) == types.ListType:
...         results = []
...         for x in some_thing:                             
...             results.append(deepTransform(some_function, x))
...         return results
...     else:
...         return some_function(some_thing)
... 
>>> deepTransform(lambda x: x*2, [1, 2, 3, 4])
[2, 4, 6, 8]
>>> deepTransform(lambda x: x*2, [1, [2, 3], 4])
[2, [4, 6], 8]
>>> deepTransform(string.upper, ['the', ['psychology', 'of'],
[[['computer']]], 'programming'])
['THE', ['PSYCHOLOGY', 'OF'], [[['COMPUTER']]], 'PROGRAMMING']
###


The only problem about deepTransform() with Xpose is that we need to think
a bit to create the right kind of function that captures what Xpose is
doing.

Also, deepTransform() is democratic in the way that it considers every
element in the list independantly of the others.  That is, in something
like:

###
>>> deepTransform(lambda x: x*2, [1, [2, 3], 4])
[2, [4, 6], 8]
###

deepTransform() does not say to the number three that: "Hey, you're the
third non-list element that I've worked on so far."  However, Xpose()
depends on that idea of list position to add an appropriate offset!  As it
is written, deepTransform() probably isn't what you're looking for.


The problems can be a little tricky.  Please feel free to ask more
questions, and we can talk about it some more.  It's definitely an
interesting problem!



Talk to you later!