0

I am trying to get an element from list and make some change on this element (which is also a list). Weirdly, the change applied on the previous list. Here is my code:

>>>sentences[0]
['<s>/<s>',
 'I/PRP',
 'need/VBP',
 'to/TO',
 'have/VB',
 'dinner/NN',
 'served/VBN',
 '</s>/</s>']
>>>sentence = sentences[0]
>>>sentence.insert(0,startc); sentence.append(endc)
>>>sentences[0]
   ['<s>/<s>',
    '<s>/<s>',
    'I/PRP',
    'need/VBP',
    'to/TO',
    'have/VB',
    'dinner/NN',
    'served/VBN',
    '</s>/</s>'
    '</s>/</s>']

It is like I just got a pointer to that element, not a copy

Coderzelf
  • 752
  • 3
  • 10
  • 26
  • The _answer_ contains info on cloning a list in Python, but the question is based on a different premise from someone explicitly wanting to learn how to clone a list. – SimonT May 11 '13 at 02:33

2 Answers2

2

You do get a "pointer", in fact. Lists (and any mutable value type!) are passed around as reference in Python.

You can make a copy of a list by passing it to the list() object constructor, or by making a full slice using [:].

a = [1,2,3]
b = a
c = list(a)
d = a[:]

a[1] = 4  # changes the list referenced by both 'a' and 'b', but not 'c' or 'd'
Amber
  • 507,862
  • 82
  • 626
  • 550
2

You're exactly right! In Python, when you pass a list as an argument to a function, or you assign a list to another variable, you're actually passing a pointer to it.

This is for efficiency reasons; if you made a separate copy of a 1000-item list every time you did one of the aforementioned things, the program would consume way too much memory and time.

To overcome this in Python, you can duplicate a one-dimensional list using = originalList[:] or = list(originalList):

sentence = sentences[0][:]     # or sentence = list(sentences[0])
sentence.insert(0,startc)
sentence.append(endc)
print(sentence)                # modified
print(sentences[0])            # not modified

Consider using list comprehension if you need to duplicate a 2D list.

SimonT
  • 2,219
  • 1
  • 18
  • 32
  • Shouldn't `sentence = sentences[0][:]` be `sentence = sentences[:][0]` – Ayush May 11 '13 at 02:31
  • 1
    @xbonez No. `[0][:]` is correct, because the issue in this case is needing to make a copy of one of the sublists, not the overall list. – Amber May 11 '13 at 02:31