5

As a beginner to programming I was trying to do this and that with Python. I wanted to have a simple function that takes a list as its arguments, and returns another list which is simply the original list rotated once (so rotate([1, 2, 3]) would return [2, 3, 1] ), while keeping the original list unaltered.

I know that this one

def rotate(list):
    list.append(list[0])
    list.remove(list[0])

would change the list in place (and return None).

But this one

def rotate_2(list):
    temp = list
    temp.append(temp[0])
    temp.remove(temp[0])
    return temp

would also change the original list in place (while returning the desired list).

And the third one

def rotate_3(list):
    temp = [x for x in list]
    temp.append(temp[0])
    temp.remove(temp[0])
    return temp

gives the desired result, that is returning a new list while keeping the original one untouched.

I can't understand the behaviour of rotate_2 . Why would list be changed when the function is just doing something on temp ? It gives me a feeling as if list and temp is 'linked' by temp = list . Also why is rotate_3 ok? Sorry if my English is strange, it's not my first language (unlike Python).

LChris314
  • 75
  • 5

1 Answers1

5

In rotate_2, temp and list refer to the same list, so when you change one, they both change.

In rotate_3, you are making a copy. A slightly more idiomatic way to make a copy is:

temp = list[:]

I personally would write this function as follows:

def rotate_4(l):
    return l[1:] + [l[0]]

This uses slicing and list concatenation.

Note that I've renamed list to l since list is a built-in name.

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • So as I understand that, `l = [1, 2]` creates a list in some kind of Python's Platonic universe and give a name `l`, and `temp = l` just gives another name for _that_ list, while `l[:]` makes a copy of `l` and slice it? – LChris314 Oct 07 '14 at 09:17
  • @LChris314: Exactly. – NPE Oct 07 '14 at 09:52