Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why i can't reverse a list of list in python

i wanted to do something like this but this code return list of None (i think it's because list.reverse() is reversing the list in place):

map(lambda row: row.reverse(), figure)

i tried this one, but the reversed return an iterator :

map(reversed, figure)

finally i did something like this , which work for me , but i don't know if it's the right solution:

def reverse(row):
    """func that reverse a list not in place"""
    row.reverse()
    return row

map(reverse, figure)

if someone has a better solution that i'm not aware of please let me know

kind regards,

like image 263
mouad Avatar asked Sep 25 '10 16:09

mouad


People also ask

How do you reverse a list in a list Python?

reverse() Method. Every list in Python has a built-in reverse() method you can call to reverse the contents of the list object in-place. Reversing the list in-place means won't create a new list and copy the existing elements to it in reverse order.

Why do I get none when I reverse a list in Python?

Return Value of reverse() in Python The reverse() function doesn't return any value. This is because it directly modifies the original list in-place without creating a new list or space.

Does Reverse () create a new list?

reverse() method in Python is a built-in method that reverses the list in place. Reversing the list in place means that the method modifies and changes the original list. It doesn't create a new list which is a copy of the original but with the list items in reverse order.


4 Answers

The mutator methods of Python's mutable containers (such as the .reverse method of lists) almost invariably return None -- a few return one useful value, e.g. the .pop method returns the popped element, but the key concept to retain is that none of those mutators returns the mutated container: rather, the container mutates in-place and the return value of the mutator method is not that container. (This is an application of the CQS principle of design -- not quite as fanatical as, say, in Eiffel, the language devised by Bertrand Meyer, who also invented CQS, but that's just because in Python "practicality beats purity, cfr import this;-).

Building a list is often costlier than just building an iterator, for the overwhelmingly common case where all you want to do is loop on the result; therefore, built-ins such as reversed (and all the wonderful building blocks in the itertools module) return iterators, not lists.

But what if you therefore have an iterator x but really truly need the equivalent list y? Piece of cake -- just do y = list(x). To make a new instance of type list, you call type list -- this is such a general Python idea that it's even more crucial to retain than the pretty-important stuff I pointed out in the first two paragraphs!-)

So, the code for your specific problem is really very easy to put together based on the crucial notions in the previous paragraphs:

[list(reversed(row)) for row in figure]

Note that I'm using a list comprehension, not map: as a rule of thumb, map should only be used as a last-ditch optimization when there is no need for a lambda to build it (if a lambda is involved then a listcomp, as well as being clearer as usual, also tends to be faster anyway!-).

Once you're a "past master of Python", if your profiling tells you that this code is a bottleneck, you can then know to try alternatives such as

[row[::-1] for row in figure]

applying a negative-step slicing (aka "Martian Smiley") to make reversed copies of the rows, knowing it's usually faster than the list(reversed(row)) approach. But -- unless your code is meant to be maintained only by yourself or somebody at least as skilled at Python -- it's a defensible position to use the simplest "code from first principles" approach except where profiling tells you to push down on the pedal. (Personally I think the "Martian Smiley" is important enough to avoid applying this good general philosophy to this specific use case, but, hey, reasonable people could differ on this very specific point!-).

like image 199
Alex Martelli Avatar answered Nov 12 '22 04:11

Alex Martelli


You can also use a slice to get the reversal of a single list (not in place):

>>> a = [1,2,3,4]
>>> a[::-1]
[4, 3, 2, 1]

So something like:

all_reversed = [lst[::-1] for lst in figure]

...or...

all_reversed = map(lambda x: x[::-1], figure)

...will do what you want.

like image 41
detly Avatar answered Nov 12 '22 03:11

detly


reversed_lists = [list(reversed(x)) for x in figure]
like image 3
supakeen Avatar answered Nov 12 '22 03:11

supakeen


map(lambda row: list(reversed(row)), figure)
like image 1
yassin Avatar answered Nov 12 '22 03:11

yassin