-4

Before running the function below, l1 is an empty list but why is it [1, 2, 3] after running the function?

def copylist(lsource, ldest):
    for e in lsource:
        ldest.append(e)
    print 'ldest =',ldest


l1 = []
l2 = [1, 2, 3]
copylist(l2, l1)
print l1  # displays [1, 2, 3]
print l2  # displays [1, 2, 3]  
juliomalegria
  • 24,229
  • 14
  • 73
  • 89
Mike Sila
  • 103
  • 1
  • 2
  • 6
  • 4
    Because that's what you wrote the function to do? It copies the data from `lsource` into `ldest`, so it copies it into `l1`. – BrenBarn Oct 05 '13 at 21:38
  • 1
    I am downvoting because based on the comments to answers, there is more to this question than you have posted above. If you want a complete answer, you need to give a complete question. – SethMMorton Oct 06 '13 at 00:56
  • Because the function is working properly. What were you expecting? – Buzz Moschetti Oct 05 '13 at 21:40
  • I expected **copylist(l2, l1)** to display **ldest [1, 2, 3]** and l1, [] after running the code. So why? – Mike Sila Oct 05 '13 at 21:52
  • It seems this is a question regarding scope. Integers strings etc have only local scope if passed as an argument to a function (and don't exist inside the function at all otherwise, unless called by global/nonlocal, right?). So why do lists, dictionaries etc. have global/nonlocal scope inside a function? I guess it's due to mutability? https://stackoverflow.com/questions/23029727/why-do-list-operations-in-python-operate-outside-of-the-function-scope – James Sep 11 '18 at 02:53

4 Answers4

1

It seems that you were expecting that lists are handled like pass-by-value as it might be in some other language. Python arguments are more like pass-by-reference, and since lists are mutable, it did exactly what you asked it to do.

The more familiar you become with Python the more obvious, natural, and even convenient this will seem.

msw
  • 42,753
  • 9
  • 87
  • 112
0

python passes objects by reference. This means you add the elements to the actual object you passed.

Hans Then
  • 10,935
  • 3
  • 32
  • 51
  • So why does **print cat** after the function call not display **Bing tiddletiddle bang** in the code [link](http://pastebin.com/YrPjb2vt) – Mike Sila Oct 06 '13 at 00:01
  • @MikeSila Why don't you copy and paste the code in the link into your question instead of making other people look for it? – SethMMorton Oct 06 '13 at 00:52
  • @MikeSila because `cat` inside the code link defines a new variable, one that is visible inside the function only. The `+` operation creates a new list, with copies of the contents of the two parameters and assigns it to `cat`. – Hans Then Oct 06 '13 at 02:27
0

For each element of lsource, if it is present in ldest, then it will be appended to ldest. For this reason, all the elements of l2 is copied to (not moved to) l1.

Peihui
  • 118
  • 1
  • 12
0

What s ldest? It's whatever you passed in. In this case, you passed in l1. ldest and l1 are the same list. It doesn't matter, therefore, what name you use to refer to the object.

kindall
  • 178,883
  • 35
  • 278
  • 309
  • So why does **print cat** after the function call not display **Bing tiddletiddle bang** in the code [link](http://pastebin.com/YrPjb2vt) – Mike Sila Oct 06 '13 at 00:07
  • Why would you expect it to? You are assigning `cat` to be `part1 + part2` at which it no longer refers to the value that was passed in. You aren't reassigning anything in the code in your question (`ldest` refers to the same thing throughout the function). – kindall Oct 06 '13 at 00:11