Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #26652 > unrolled thread
| Started by | Mok-Kong Shen <mok-kong.shen@t-online.de> |
|---|---|
| First post | 2012-08-06 21:50 +0200 |
| Last post | 2012-08-20 13:43 -0700 |
| Articles | 7 — 5 participants |
Back to article view | Back to comp.lang.python
A difficulty with lists Mok-Kong Shen <mok-kong.shen@t-online.de> - 2012-08-06 21:50 +0200
Re: A difficulty with lists MRAB <python@mrabarnett.plus.com> - 2012-08-06 21:19 +0100
Re: A difficulty with lists Madison May <worldpeaceagentforchange@gmail.com> - 2012-08-15 14:12 -0700
Re: A difficulty with lists Terry Reedy <tjreedy@udel.edu> - 2012-08-15 20:21 -0400
Re: A difficulty with lists Madison May <worldpeaceagentforchange@gmail.com> - 2012-08-16 06:46 -0700
Re: A difficulty with lists Madison May <worldpeaceagentforchange@gmail.com> - 2012-08-15 16:56 -0700
Re: A difficulty with lists Cheng <chbeh88@googlemail.com> - 2012-08-20 13:43 -0700
| From | Mok-Kong Shen <mok-kong.shen@t-online.de> |
|---|---|
| Date | 2012-08-06 21:50 +0200 |
| Subject | A difficulty with lists |
| Message-ID | <jvp75j$opr$1@news.albasani.net> |
I ran the following code:
def xx(nlist):
print("begin: ",nlist)
nlist+=[999]
print("middle:",nlist)
nlist=nlist[:-1]
print("final: ",nlist)
u=[1,2,3,4]
print(u)
xx(u)
print(u)
and obtained the following result:
[1, 2, 3, 4]
begin: [1, 2, 3, 4]
middle: [1, 2, 3, 4, 999]
final: [1, 2, 3, 4]
[1, 2, 3, 4, 999]
As beginner I couldn't understand why the last line wasn't [1, 2, 3, 4].
Could someone kindly help?
M. K. Shen
[toc] | [next] | [standalone]
| From | MRAB <python@mrabarnett.plus.com> |
|---|---|
| Date | 2012-08-06 21:19 +0100 |
| Message-ID | <mailman.3029.1344284341.4697.python-list@python.org> |
| In reply to | #26652 |
On 06/08/2012 20:50, Mok-Kong Shen wrote:
> I ran the following code:
>
> def xx(nlist):
> print("begin: ",nlist)
> nlist+=[999]
> print("middle:",nlist)
> nlist=nlist[:-1]
> print("final: ",nlist)
>
> u=[1,2,3,4]
> print(u)
> xx(u)
> print(u)
>
> and obtained the following result:
>
> [1, 2, 3, 4]
> begin: [1, 2, 3, 4]
> middle: [1, 2, 3, 4, 999]
> final: [1, 2, 3, 4]
> [1, 2, 3, 4, 999]
>
> As beginner I couldn't understand why the last line wasn't [1, 2, 3, 4].
> Could someone kindly help?
>
This:
nlist+=[999]
appends to the list, making it [1, 2, 3, 4, 999].
This:
nlist=nlist[:-1]
gets a slice of the list and then binds it to the local name 'nlist'.
[toc] | [prev] | [next] | [standalone]
| From | Madison May <worldpeaceagentforchange@gmail.com> |
|---|---|
| Date | 2012-08-15 14:12 -0700 |
| Message-ID | <16702a22-6ce3-4120-bbcc-9649e1717130@googlegroups.com> |
| In reply to | #26652 |
On Monday, August 6, 2012 3:50:13 PM UTC-4, Mok-Kong Shen wrote:
> I ran the following code:
>
>
>
> def xx(nlist):
>
> print("begin: ",nlist)
>
> nlist+=[999]
>
> print("middle:",nlist)
>
> nlist=nlist[:-1]
>
> print("final: ",nlist)
>
>
>
> u=[1,2,3,4]
>
> print(u)
>
> xx(u)
>
> print(u)
>
>
>
> and obtained the following result:
>
>
>
> [1, 2, 3, 4]
>
> begin: [1, 2, 3, 4]
>
> middle: [1, 2, 3, 4, 999]
>
> final: [1, 2, 3, 4]
>
> [1, 2, 3, 4, 999]
>
>
>
> As beginner I couldn't understand why the last line wasn't [1, 2, 3, 4].
>
> Could someone kindly help?
>
>
>
> M. K. Shen
The list nlist inside of function xx is not the same as the variable u outside of the function: nlist and u refer to two separate list objects. When you modify nlist, you are not modifying u. If you wanted the last line to be [1, 2, 3, 4], you could use the code below:
#BEGIN CODE
def xx(nlist):
print("begin: ",nlist)
nlist+=[999]
print("middle:",nlist)
nlist=nlist[:-1]
print("final: ",nlist)
return nlist
u=[1,2,3,4]
print(u)
u = xx(u)
print(u)
#END CODE
Notice that I changed two things. First, the function xx(nlist) returns nlist. Secondly, u is reassigned to the result of xx(nlist).
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-08-15 20:21 -0400 |
| Message-ID | <mailman.3334.1345076503.4697.python-list@python.org> |
| In reply to | #27113 |
On 8/15/2012 5:58 PM, Rob Day wrote: > Madison May wrote: > The list nlist inside of function xx is not the same as the variable > u outside of the function: nlist and u refer to two separate list > objects. When you modify nlist, you are not modifying u. > <http://mail.python.org/mailman/listinfo/python-list> This is confused and wrong. The parameter *name* 'nlist' of function xx is not the same as the *name* 'u' outside the function. The call xx(u) binds nlist to the same object that u is bound to. At that point, the two name *are* bound to the same list object. The statement "nlist+=[999]" dodifying nlist *does* modify u. The subsequent assignment statement "nlist=nlist[:-1]" rebinds 'nlist' to a *new* list object. That new object gets deleted when the function returns. So the rebinding is completely useless. This sequence, modifying the input argument and then rebinding to a new object, is bad code. > Well - that's not quite true. Before calling the function, u is [1, 2, > 3, 4] - but after calling the function, u is [1, 2, 3, 4, 999]. This is > a result of using 'nlist += [999]' - the same thing doesn't happen if > you use 'nlist = nlist+[999]' instead. > > I'm not completely aware of what's going on behind the scenes here, but you got it right. > I think the problem is that 'nlist' is actually a reference to a list > object - it points to the same place as u. Calling a python function binds parameter names to argument objects or (for *args and **kwds parameters) a collection based on argument objects. > When you assign to it within > the function, then it becomes separate from u - which is why nlist = > nlist+[999] and nlist = nlist[:-1] don't modify u - but if you modify > nlist in place before doing that, such as by using +=, then it's still > pointing to u, and so u gets modified as well. -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Madison May <worldpeaceagentforchange@gmail.com> |
|---|---|
| Date | 2012-08-16 06:46 -0700 |
| Message-ID | <480fc764-16bd-4ce8-8518-fe0366c8c25e@googlegroups.com> |
| In reply to | #27126 |
On Wednesday, August 15, 2012 8:21:22 PM UTC-4, Terry Reedy wrote: > On 8/15/2012 5:58 PM, Rob Day wrote: > > Yeah, my apologies for any confusion I created. Although I suppose my explanation would be somewhat true for immutable objects since they can't be modified in-place (any modification at all would cause the creation of a new immutable object right?), I now understand that it is completely and totally wrong for mutable objects. Thanks for the in-depth explanations, Terry and Rob. I feel like I have a much more solid grasp of what's going on behind the scenes after your analysis. > > > Madison May wrote: > > > The list nlist inside of function xx is not the same as the variable > > > u outside of the function: nlist and u refer to two separate list > > > objects. When you modify nlist, you are not modifying u. > > > <http://mail.python.org/mailman/listinfo/python-list> > > > > This is confused and wrong. The parameter *name* 'nlist' of function xx > > is not the same as the *name* 'u' outside the function. The call xx(u) > > binds nlist to the same object that u is bound to. At that point, the > > two name *are* bound to the same list object. The statement > > "nlist+=[999]" dodifying nlist *does* modify u. The subsequent > > assignment statement "nlist=nlist[:-1]" rebinds 'nlist' to a *new* list > > object. That new object gets deleted when the function returns. So the > > rebinding is completely useless. > > > > This sequence, modifying the input argument and then rebinding to a new > > object, is bad code. > > > > > Well - that's not quite true. Before calling the function, u is [1, 2, > > > 3, 4] - but after calling the function, u is [1, 2, 3, 4, 999]. This is > > > a result of using 'nlist += [999]' - the same thing doesn't happen if > > > you use 'nlist = nlist+[999]' instead. > > > > > > I'm not completely aware of what's going on behind the scenes here, but > > > > you got it right. > > > > > I think the problem is that 'nlist' is actually a reference to a list > > > object - it points to the same place as u. > > > > Calling a python function binds parameter names to argument objects or > > (for *args and **kwds parameters) a collection based on argument objects. > > > > > When you assign to it within > > > the function, then it becomes separate from u - which is why nlist = > > > nlist+[999] and nlist = nlist[:-1] don't modify u - but if you modify > > > nlist in place before doing that, such as by using +=, then it's still > > > pointing to u, and so u gets modified as well. > > > > > > -- > > Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Madison May <worldpeaceagentforchange@gmail.com> |
|---|---|
| Date | 2012-08-15 16:56 -0700 |
| Message-ID | <275392ae-09e2-469d-a9e3-43a9f50eece5@googlegroups.com> |
| In reply to | #26652 |
On Monday, August 6, 2012 3:50:13 PM UTC-4, Mok-Kong Shen wrote:
> I ran the following code:
>
>
>
> def xx(nlist):
>
> print("begin: ",nlist)
>
> nlist+=[999]
>
> print("middle:",nlist)
>
> nlist=nlist[:-1]
>
> print("final: ",nlist)
>
>
>
> u=[1,2,3,4]
>
> print(u)
>
> xx(u)
>
> print(u)
>
>
>
> and obtained the following result:
>
>
>
> [1, 2, 3, 4]
>
> begin: [1, 2, 3, 4]
>
> middle: [1, 2, 3, 4, 999]
>
> final: [1, 2, 3, 4]
>
> [1, 2, 3, 4, 999]
>
>
>
> As beginner I couldn't understand why the last line wasn't [1, 2, 3, 4].
>
> Could someone kindly help?
>
>
>
> M. K. Shen
I've modified your code slightly so you can see what's happening with u in the middle of function xx. Take a look:
u=[1,2,3,4]
def xx(nlist):
print("xx(u)\n")
print("At first, u and nlist refer to the same list")
print("nlist: %s u: %s\n" % (nlist, u))
nlist+=[999]
print("nlist+=[999]\n")
print("The list has been modified in place. u and nlist are still equal")
print("nlist: %s u: %s\n" %(nlist, u))
nlist=nlist[:-1]
print("nlist=nlist[:1]\n")
print("Now nlist refers to a new list object in memory that was created by")
print("taking a slice of u. u and nlist are no longer equal.")
print("nlist: %s u: %s" %(nlist, u))
xx(u)
Here's the output:
xx(u)
At first, u and nlist refer to the same list
nlist: [1, 2, 3, 4] u: [1, 2, 3, 4]
nlist+=[999]
The list has been modified in place. u and nlist are still equal
nlist: [1, 2, 3, 4, 999] u: [1, 2, 3, 4, 999]
nlist=nlist[:1]
Now nlist refers to a new list object in memory that was created by
taking a slice of u. u and nlist are no longer equal.
nlist: [1, 2, 3, 4] u: [1, 2, 3, 4, 999]
Thank you, Rob Day, for explaining a some of what's happening behind the scenes.
[toc] | [prev] | [next] | [standalone]
| From | Cheng <chbeh88@googlemail.com> |
|---|---|
| Date | 2012-08-20 13:43 -0700 |
| Message-ID | <66aafdc3-7ea5-4401-859b-89cd5bf268a8@googlegroups.com> |
| In reply to | #26652 |
On Monday, August 6, 2012 12:50:13 PM UTC-7, Mok-Kong Shen wrote:
> I ran the following code:
>
>
>
> def xx(nlist):
>
> print("begin: ",nlist)
>
> nlist+=[999]
>
> print("middle:",nlist)
>
> nlist=nlist[:-1]
>
> print("final: ",nlist)
>
>
>
> u=[1,2,3,4]
>
> print(u)
>
> xx(u)
>
> print(u)
>
>
>
> and obtained the following result:
>
>
>
> [1, 2, 3, 4]
>
> begin: [1, 2, 3, 4]
>
> middle: [1, 2, 3, 4, 999]
>
> final: [1, 2, 3, 4]
>
> [1, 2, 3, 4, 999]
>
>
>
> As beginner I couldn't understand why the last line wasn't [1, 2, 3, 4].
>
> Could someone kindly help?
>
>
>
> M. K. Shen
When you pass a list (mutable object) to a function, the pointer to the list is passed to the function and the corresponding argument points to the same memory location as the pointer passed in. So in this case, nlist points to the same memory location which u points to when xx is called, i.e. nlist and u points to same memory location which contains [1,2,3,4].
nlist += [999] is equivalent to nlist.extend([999]). This statement adds the argument list to the original list, i.e. the memory location pointed by nlist and u now contains [1,2,3,4,999]. So, print(u) after calling xx will print [1,2,3,4,999].
nlist += [999] is not the same as nlist = nlist + [999]. In the later case, nlist + [999] will create a new memory location containing the two lists combined and rebind nlist to the new location, i.e. nlist points to a new memory location that has [1,2,3,4,999]. So if nlist = nlist +[999] is used, the original memory location containing [1,2,3,4] is untouched, and print(u) after calling xx will print [1,2,3,4]
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web