8

I'm trying to use the reverse() method in the following way:

>>> L=[1,2,3]
>>> R=L
>>> L.reverse()
>>> L
[3, 2, 1]
>>> R
[3, 2, 1]

Why does it reverse R as well? How do I keep the original list and create a reversed on?

Thanks!

campeterson
  • 3,591
  • 2
  • 25
  • 26
Hana
  • 535
  • 2
  • 7
  • 17

6 Answers6

7

you need to make a copy of your list

L=[1,2,3]
# R=L
R = L[:]
L.reverse()

or more directly (reversing using slice notation):

R = L[::-1]

if you just write R = L then R is just a new reference on the same list L.

if you also need to copy the elements in your list, use copy.deepcopy; R = L[:] only produces a shallow copy (which is fine in your case where there are only ints in the list).

hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
  • 3
    Mind you, the simplest solution is to combine the shallow copy slice with reversal, to get the canonical reversing slice: `R = L[::-1]` – ShadowRanger Oct 11 '18 at 02:32
1

To avoid reversing R, you need a copy of L

To make a copy, change

R=L    <---- this is not copying L in to R

to

R= L[:]    <---- this will create a copy of L in to R
Yousaf
  • 27,861
  • 6
  • 44
  • 69
1
>>> L=[1,2,3]
>>> R=list(reversed(L))
>>> R
[3, 2, 1]
>>> L
[1, 2, 3]
campeterson
  • 3,591
  • 2
  • 25
  • 26
0

This will do

R = L[:]

Read about copying and deep copying to understand why this is happening. In short, it is because when you do R = L, both point to the "same" list in memory so reversing one will reverse the other.

Alternately you can use deepcopy

Priyatham
  • 2,821
  • 1
  • 19
  • 33
0

The operation

R=L

means that the variable R stores whatever L is storing i.e R references to whatever value L is refering. Now, when you reverse L, it means the list L is refering to is reversed.As R is also refereing same address, you are seeing R as reversed.

AV94
  • 1,824
  • 3
  • 23
  • 36
0

You have been bitten by the fact that Python assigns references, not copies.

Python uses reference exclusively in order to prevent unneeded copies. It uses references also when passing function arguments, and even with default function arguments. It only makes a copy when you explicitly tell it to, e.g. by doing

L = list(R)

or

from copy import copy
L = copy(R)

The difference between the two is that list(R) always returns a list, where copy returns an object of the same type as the original. Also, copy does not work with iterators, but list does.

Note that these are 'shallow' copies. If the list contains objects, the new list contains references to the same objects. For 'deep' copies, it has the function deepcopy in the module copy.

from copy import deepcopy
L = deepcopy(R)

But in practise there is rarely a need to make explicit copies. Python provides e.g. the reversed built-in that can be used to iterate through the list.

for l in reversed(L):
    # do stuff

It returns an iterator, so it is efficient. No need to duplicate the list. Other cases where a copy might be needed can be handled by e.g. generator functions. A valid case for a copy might be when pasing data past thread boundaries.

EvertW
  • 1,160
  • 9
  • 18
  • Thanks. I tried that but I get: >>> L=[1,2,3] >>> R=reversed(L) >>> R >> What do I do wrong? – Hana Jan 21 '17 at 09:32
  • The result of `reversed` is not for storing in a variable, but for use in a for loop (or list comprehension). No need to store duplicate data... I have updated my answer. – EvertW Jan 21 '17 at 09:45
  • @Hana you need `R=list(reversed(L))` – campeterson Oct 10 '18 at 22:42