Dear Folks,

I am trying to use python-idiom to reverse a list of lists so that, for example,

a = [[1, 2], ['apple', 'orange']]

becomes

b = [['orange', 'apple'], [2, 1]]

My code for this at present is:

import copy

a = [[1, 2], ["apple", "orange"]]
if type(a) is list:
	b = copy.deepcopy(a)
	for item in b:
		(map(item.reverse(), item))
b = map(b.reverse(), b)
print a, b

Is there a simpler, more elegant, pythonesque way to do this using map(), filter(), reduce() and friends and possibly recursion?

Thank you.

That's going to be a tougher one if I think you are asking for a procedure that can work on lists with mixed items in them down to an arbitrary number of levels.

In a real application you could probably find a better way of representing the data and use simpler programming logic to access it.

You could try something like this

def mirrored(listtree):
    return [(mirrored(x) if isinstance(x, list) else x)
                             for x in reversed(listtree)]

then

>>> a=[[1, 2], ['apple', 'orange']]
>>> mirrored(a)
[['orange', 'apple'], [2, 1]]
>>> a=[[1, 2], [['apple', 'banana', 5], 'orange']]
>>> mirrored(a)
[['orange', [5, 'banana', 'apple']], [2, 1]]

Edited 6 Years Ago by Gribouillis: n/a

That's a good solution, Gribouillis. I was wondering if something like that would work. Nice use of "isinstance" to allow users to pass subclasses of lists as an argument. Would we want to use duck typing to allow other sequences?

I don't know if it will be useful, but lists have a method called "reverse" that will reverse the items of a list 'in place', meaning that the original list is reversed instead of a copy returned.

That's a good solution, Gribouillis. I was wondering if something like that would work. Nice use of "isinstance" to allow users to pass subclasses of lists as an argument. Would we want to use duck typing to allow other sequences?

I don't know if it will be useful, but lists have a method called "reverse" that will reverse the items of a list 'in place', meaning that the original list is reversed instead of a copy returned.

I don't think there is a "natural" way to generalize to other types of sequences. So, better write a specific function for a specific type. Otherwise we'll be writing code that will never be used :)

You're probably right. It'd be especially tough considering that you'd want to return the same type of object and many sequences don't support the "reversed" method.

That took my breath away, Gribouillis. Thank you.

I have two questions:

1. If one wanted to confirm that

listtree

is indeed a list, does one need to do anything more?

2. Does the

for x in reversed(listtree)

get done befroe the rest of the expression? Pardon me if this is naive but I am new to python and not too experienced in recursion.

Thank you.

If you don't know that listtree is already a list, you can write it this way

def mirrored(item):
    if isinstance(item, list):
        return list(mirrored(x) for x in reversed(item))
    else:
        return item

About, the 'list comprehension syntax', when you write

mylist = [ function(x) for x in sequence if condition(x) ] # or list(...)

it has the same effect as

mylist = [] # or list()
for x in sequence:
    if condition(x):
        mylist.append(function(x))

except that the append method is not called.

Edited 6 Years Ago by Gribouillis: n/a

This question has already been answered. Start a new discussion instead.