List understanding and apply methods

I'm just trying to figure out what's going on during list comprehension. Some of the methods that work on in-place lists don't seem to work when applied in a list comprehension:

a = [[1, 2, 3], [4, 5, 6]]
i1 = id(a[0])

for i in a: i.reverse()
>>> [[3, 2, 1], [6, 5, 4]  # Works
print i1 == id(a[0])  # True, same memory address

a = [i.reverse() for i in a]
>>> [None, None]  # Doesn't work
print i1 == id(a[0])  # False, new memory address

a = [i[::-1] for i in a]
>>> [[3, 2, 1], [6, 5, 4]]  # Works!
print i1 == id(a[0])  # False

      

I'm guessing it has something to do with all the elements that are copied to another memory space. Why i[::-1]

does it work, but i.reverse()

not?

+3


source to share


4 answers


i.reverse()

swaps the array in place and returns nothing, which means it returns a type None

. This way you get [None, None]

from the list and the elements of the previous array change at the same time.



The two should not be confused with either use for

and x.reverse()

, or use reversed(x)

or x[::-1]

in the comprehension of the list.

+7


source


i.reverse()

cancels the list in place and returns None

.

What docs say:

list.reverse()

Reverse the list items in place

against.

reversed(seq)

Return a reverse iterator. seq must be an object that has __reversed__()

or supports a sequencing protocol (method __len__()

and method __getitem__()

with integer arguments starting with 0

).

<strong> Examples:



>>> xs = [1, 2, 3]
>>> id(xs)
140625121860208
>>> ys = xs[::-1]
>>> id(ys)
140625121924088

      

Slicing creates a new list.

>>> xs.reverse()
>>> xs
[3, 2, 1]
>>> id(xs)
140625121860208

      

Sorting / reversing in place keeps the original list.

>>> zs = list(reversed(xs))
>>> zs
[1, 2, 3]
>>> id(zs)
140625121976400

      

reversed()

returns an iterator; which, when it turns into a list, creates a new list! If you read PEP 0322 - Reverse Iteration , you will notice that it reversed()

does not create a new data structure, but simply iterates the sequence in reverse order.

+3


source


This does what you intend:

>>> a = [[1, 2, 3], [4, 5, 6]]
>>> [list(reversed(i)) for i in a]
[[3, 2, 1], [6, 5, 4]]

      

The List comprehension always returns a new list, so use the reverse

method returns a return value reverse

that is None

.

The function reversed()

gives you a new iterator. Converting it to a list for your example is the same as:

>>> [i[::-1] for i in a] 

      

Although they look very similar, it is important to distinguish between both, function reversed()

and methodobj.reverse()

+1


source


list.reverse

cancels the list in place and returns None

. while slice a[::-1]

creates another list and returns it as a value.

a list comprehension will take return value

every expression.

0


source







All Articles