Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #6295 > unrolled thread

Puzzled by list-appending behavior

Started byUncle Ben <bgreen@nycap.rr.com>
First post2011-05-25 21:46 -0700
Last post2011-05-26 17:36 -0400
Articles 20 on this page of 21 — 11 participants

Back to article view | Back to comp.lang.python


Contents

  Puzzled by list-appending behavior Uncle Ben <bgreen@nycap.rr.com> - 2011-05-25 21:46 -0700
    Re: Puzzled by list-appending behavior Ben Finney <ben+python@benfinney.id.au> - 2011-05-26 15:11 +1000
    Re: Puzzled by list-appending behavior Chris Rebert <clp2@rebertia.com> - 2011-05-25 22:17 -0700
    Re: Puzzled by list-appending behavior Chris Angelico <rosuav@gmail.com> - 2011-05-26 17:20 +1000
    Re: Puzzled by list-appending behavior Chris Angelico <rosuav@gmail.com> - 2011-05-26 17:23 +1000
    Re: Puzzled by list-appending behavior Uncle Ben <bgreen@nycap.rr.com> - 2011-05-26 00:33 -0700
    Re: Puzzled by list-appending behavior Chris Rebert <clp2@rebertia.com> - 2011-05-26 01:09 -0700
    Re: Puzzled by list-appending behavior MRAB <python@mrabarnett.plus.com> - 2011-05-26 16:58 +0100
      Re: Puzzled by list-appending behavior Tim Roberts <timr@probo.com> - 2011-05-26 23:34 -0700
        Re: Puzzled by list-appending behavior MRAB <python@mrabarnett.plus.com> - 2011-05-27 17:02 +0100
    Re: Puzzled by list-appending behavior Chris Angelico <rosuav@gmail.com> - 2011-05-27 02:04 +1000
    Re: Puzzled by list-appending behavior John Ladasky <ladasky@my-deja.com> - 2011-05-26 11:27 -0700
      Re: Puzzled by list-appending behavior Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-05-27 01:59 +0000
        Re: Puzzled by list-appending behavior Chris Angelico <rosuav@gmail.com> - 2011-05-27 13:24 +1000
          Re: Puzzled by list-appending behavior Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-05-27 03:52 +0000
            Re: Puzzled by list-appending behavior Chris Angelico <rosuav@gmail.com> - 2011-05-27 14:10 +1000
            RE: Puzzled by list-appending behavior "Prasad, Ramit" <ramit.prasad@jpmchase.com> - 2011-05-27 13:58 -0400
            Re: Puzzled by list-appending behavior Ethan Furman <ethan@stoneleaf.us> - 2011-05-27 11:56 -0700
    Re: Puzzled by list-appending behavior Terry Reedy <tjreedy@udel.edu> - 2011-05-26 14:44 -0400
    RE: Puzzled by list-appending behavior "Prasad, Ramit" <ramit.prasad@jpmchase.com> - 2011-05-26 15:34 -0400
    Re: Puzzled by list-appending behavior Terry Reedy <tjreedy@udel.edu> - 2011-05-26 17:36 -0400

Page 1 of 2  [1] 2  Next page →


#6295 — Puzzled by list-appending behavior

FromUncle Ben <bgreen@nycap.rr.com>
Date2011-05-25 21:46 -0700
SubjectPuzzled by list-appending behavior
Message-ID<16c21256-48df-416a-971f-de49ca4cc981@x6g2000yqj.googlegroups.com>
In playing with lists of lists, I found the following:

(In 3.1, but the same happens also in 2.7)

list = [1,2,3]
list.append ( [4,5,6] )
x = list
x   ->
    [1,2,3,[4,5,6]]
as expected.

But the shortcut fails:

list=[1,2,3]
x = list.append( [4,5,6] )
x   ->
   nothing

Can someone explain this to me?

Uncle Ben

[toc] | [next] | [standalone]


#6297

FromBen Finney <ben+python@benfinney.id.au>
Date2011-05-26 15:11 +1000
Message-ID<87ei3mavvn.fsf@benfinney.id.au>
In reply to#6295
Uncle Ben <bgreen@nycap.rr.com> writes:

> Can someone explain this to me?

Yes, the documentation for that function (‘list.append’) can explain it.

In short: if a method modifies the instance, that method does not return
the instance. This policy holds for the built-in types, and should be
followed for user-defined types also.

-- 
 \      “[I]t is impossible for anyone to begin to learn that which he |
  `\                thinks he already knows.” —Epictetus, _Discourses_ |
_o__)                                                                  |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#6298

FromChris Rebert <clp2@rebertia.com>
Date2011-05-25 22:17 -0700
Message-ID<mailman.2108.1306387068.9059.python-list@python.org>
In reply to#6295
On Wed, May 25, 2011 at 9:46 PM, Uncle Ben <bgreen@nycap.rr.com> wrote:
> In playing with lists of lists, I found the following:
>
> (In 3.1, but the same happens also in 2.7)
>
> list = [1,2,3]
> list.append ( [4,5,6] )

Note the lack of output after this line. This indicates that
list.append([4,5,6]) returned None. Contrast this with, say,
list.pop().

> x = list
> x   ->
>    [1,2,3,[4,5,6]]
> as expected.
>
> But the shortcut fails:
>
> list=[1,2,3]
> x = list.append( [4,5,6] )
> x   ->
>   nothing
>
> Can someone explain this to me?

The append() method does *not* return the now-appended-to list. It is
a mutator method that modifies the list object in-place; per
convention, it therefore returns None to reinforce its side-effecting
nature to the user (the interactive interpreter by default does not
display None expression results); analogous methods in other languages
return void.

list.remove(), list.sort(), and list.extend() similarly return None
rather than the now-modified list.

Cheers,
Chris
--
http://rebertia.com

[toc] | [prev] | [next] | [standalone]


#6300

FromChris Angelico <rosuav@gmail.com>
Date2011-05-26 17:20 +1000
Message-ID<mailman.2111.1306394456.9059.python-list@python.org>
In reply to#6295
On Thu, May 26, 2011 at 2:46 PM, Uncle Ben <bgreen@nycap.rr.com> wrote:
> In playing with lists of lists, I found the following:
>
> (In 3.1, but the same happens also in 2.7)
>
> list = [1,2,3]

Ben Finney has already answered the main question, but as a side
point, I would generally avoid creating a variable called 'list'.
That's the name of the type (Python 2) or class (Python 3) of all
lists, so it might result in confusion if you have an actual list with
that name.

If you want the behaviour of joining two lists (or adding something to
a list) and saving the result elsewhere, you can use the plain
addition:

a=[1,2,3]
b=a+[[4,5,6]]

Note that you have to add a list, and it will append the contents of that list.

Chris Angelico

[toc] | [prev] | [next] | [standalone]


#6301

FromChris Angelico <rosuav@gmail.com>
Date2011-05-26 17:23 +1000
Message-ID<mailman.2112.1306394584.9059.python-list@python.org>
In reply to#6295
On Thu, May 26, 2011 at 5:20 PM, Chris Angelico <rosuav@gmail.com> wrote:
>
> Ben Finney has already answered the main question

Giving credit where credit's due, it was more Chris Rebert's post that
answered the question. Sorry Chris!

Chris Angelico

[toc] | [prev] | [next] | [standalone]


#6302

FromUncle Ben <bgreen@nycap.rr.com>
Date2011-05-26 00:33 -0700
Message-ID<b7435154-da73-47c9-b106-cd301e5c83ac@z13g2000yqg.googlegroups.com>
In reply to#6295
On May 26, 12:46 am, Uncle Ben <bgr...@nycap.rr.com> wrote:
> In playing with lists of lists, I found the following:
>
> (In 3.1, but the same happens also in 2.7)
>
> list = [1,2,3]
> list.append ( [4,5,6] )
> x = list
> x   ->
>     [1,2,3,[4,5,6]]
> as expected.
>
> But the shortcut fails:
>
> list=[1,2,3]
> x = list.append( [4,5,6] )
> x   ->
>    nothing
>
> Can someone explain this to me?
>
> Uncle Ben

Thank you all.  It is wonderful to have this community as a resource.

Uncle Ben

[toc] | [prev] | [next] | [standalone]


#6303

FromChris Rebert <clp2@rebertia.com>
Date2011-05-26 01:09 -0700
Message-ID<mailman.2114.1306397385.9059.python-list@python.org>
In reply to#6295
On Thu, May 26, 2011 at 12:23 AM, Chris Angelico <rosuav@gmail.com> wrote:
> On Thu, May 26, 2011 at 5:20 PM, Chris Angelico <rosuav@gmail.com> wrote:
>>
>> Ben Finney has already answered the main question
>
> Giving credit where credit's due, it was more Chris Rebert's post that
> answered the question. Sorry Chris!

Eh, one can't fight chronology!

I'm just surprised that the docstring doesn't explicitly state
"Returns None." by this point, given that this is such a common point
of newbie confusion.

Cheers,
Chris

[toc] | [prev] | [next] | [standalone]


#6324

FromMRAB <python@mrabarnett.plus.com>
Date2011-05-26 16:58 +0100
Message-ID<mailman.2119.1306425499.9059.python-list@python.org>
In reply to#6295
On 26/05/2011 06:17, Chris Rebert wrote:
> On Wed, May 25, 2011 at 9:46 PM, Uncle Ben<bgreen@nycap.rr.com>  wrote:
>> In playing with lists of lists, I found the following:
>>
>> (In 3.1, but the same happens also in 2.7)
>>
>> list = [1,2,3]
>> list.append ( [4,5,6] )
>
> Note the lack of output after this line. This indicates that
> list.append([4,5,6]) returned None. Contrast this with, say,
> list.pop().
>
>> x = list
>> x   ->
>>     [1,2,3,[4,5,6]]
>> as expected.
>>
>> But the shortcut fails:
>>
>> list=[1,2,3]
>> x = list.append( [4,5,6] )
>> x   ->
>>    nothing
>>
>> Can someone explain this to me?
>
> The append() method does *not* return the now-appended-to list. It is
> a mutator method that modifies the list object in-place; per
> convention, it therefore returns None to reinforce its side-effecting
> nature to the user (the interactive interpreter by default does not
> display None expression results); analogous methods in other languages
> return void.
>
> list.remove(), list.sort(), and list.extend() similarly return None
> rather than the now-modified list.
>
I'd just like to point out that it's a convention, not a rigid rule.
Sometimes it's not followed, for example, dict.setdefault.

[toc] | [prev] | [next] | [standalone]


#6372

FromTim Roberts <timr@probo.com>
Date2011-05-26 23:34 -0700
Message-ID<4dhut6lr8aqtfrk6oljr9lmofra6l5rp53@4ax.com>
In reply to#6324
MRAB <python@mrabarnett.plus.com> wrote:
>
>I'd just like to point out that it's a convention, not a rigid rule.

Reminds me of the catch-phrase from the first Pirates of the Caribbean
movie: "It's more of a guideline than a rule."
-- 
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

[toc] | [prev] | [next] | [standalone]


#6407

FromMRAB <python@mrabarnett.plus.com>
Date2011-05-27 17:02 +0100
Message-ID<mailman.2151.1306512129.9059.python-list@python.org>
In reply to#6372
On 27/05/2011 07:34, Tim Roberts wrote:
> MRAB<python@mrabarnett.plus.com>  wrote:
>>
>> I'd just like to point out that it's a convention, not a rigid rule.
>
> Reminds me of the catch-phrase from the first Pirates of the Caribbean
> movie: "It's more of a guideline than a rule."

Much like the Zen of Python.

[toc] | [prev] | [next] | [standalone]


#6325

FromChris Angelico <rosuav@gmail.com>
Date2011-05-27 02:04 +1000
Message-ID<mailman.2120.1306425845.9059.python-list@python.org>
In reply to#6295
On Fri, May 27, 2011 at 1:58 AM, MRAB <python@mrabarnett.plus.com> wrote:
> I'd just like to point out that it's a convention, not a rigid rule.
> Sometimes it's not followed, for example, dict.setdefault.

dict.setdefault is more like dict.get but it also stores the result.
It's probably more a name issue than a protocol issue.

Chris Angelico

[toc] | [prev] | [next] | [standalone]


#6333

FromJohn Ladasky <ladasky@my-deja.com>
Date2011-05-26 11:27 -0700
Message-ID<829f09b0-8f46-4ef0-9d25-e15a1629e22d@h12g2000pro.googlegroups.com>
In reply to#6295
On May 25, 9:46 pm, Uncle Ben <bgr...@nycap.rr.com> wrote:

> list = [1,2,3]

Somewhat unrelated, but... is it a good idea to name your list
"list"?  Isn't that the name of Python's built-in list constructor
method?

Shadowing a built-in has contributed to more than one subtle bug in my
code, and I've learned to avoid it.

[toc] | [prev] | [next] | [standalone]


#6360

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-05-27 01:59 +0000
Message-ID<4ddf0584$0$29996$c3e8da3$5496439d@news.astraweb.com>
In reply to#6333
On Thu, 26 May 2011 11:27:35 -0700, John Ladasky wrote:

> On May 25, 9:46 pm, Uncle Ben <bgr...@nycap.rr.com> wrote:
> 
>> list = [1,2,3]
> 
> Somewhat unrelated, but... is it a good idea to name your list "list"? 
> Isn't that the name of Python's built-in list constructor method?
> 
> Shadowing a built-in has contributed to more than one subtle bug in my
> code, and I've learned to avoid it.

Agreed. However, there are good reasons for sometimes shadowing built-
ins, and namespaces make it safe to do so if you are sufficiently careful.

E.g. I have a module stats.sum() which shadows the built-in, but only in 
that module, which is exactly the behaviour I want. 

(If you do "from stats import sum", then you're responsible for whatever 
happens next.)

Or you might isolate the shadow to a function small enough that you can 
be sure that it won't cause any problems, e.g.:

def get(list, object):
    """Append object to a copy of list and return it."""
    return list + [object]

For one or two line functions, I think that's perfectly reasonable. 
Anything more than that, I'd be getting nervous.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#6365

FromChris Angelico <rosuav@gmail.com>
Date2011-05-27 13:24 +1000
Message-ID<mailman.2142.1306466667.9059.python-list@python.org>
In reply to#6360
On Fri, May 27, 2011 at 11:59 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> def get(list, object):
>    """Append object to a copy of list and return it."""
>    return list + [object]
>
> For one or two line functions, I think that's perfectly reasonable.
> Anything more than that, I'd be getting nervous.

But even for something that short, why do it? Why not call the
parameter 'lst' or something? Shadowing with something completely
different is seldom going to give major advantage, and has the
potential to be quite confusing.

Chris Angelico

[toc] | [prev] | [next] | [standalone]


#6368

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-05-27 03:52 +0000
Message-ID<4ddf2003$0$29996$c3e8da3$5496439d@news.astraweb.com>
In reply to#6365
On Fri, 27 May 2011 13:24:24 +1000, Chris Angelico wrote:

> On Fri, May 27, 2011 at 11:59 AM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> def get(list, object):
>>    """Append object to a copy of list and return it.""" return list +
>>    [object]
>>
>> For one or two line functions, I think that's perfectly reasonable.
>> Anything more than that, I'd be getting nervous.
> 
> But even for something that short, why do it? Why not call the parameter
> 'lst' or something? Shadowing with something completely different is
> seldom going to give major advantage, and has the potential to be quite
> confusing.

Because "lst" is not a real word. To native readers of languages derived 
from Latin or Germany, such as English, it is quite a strange "word" 
because it has no vowel. In addition, it looks like 1st (first).

We use naming conventions like my_list list_ lst alist etc. to avoid 
shadowing the built-in list, not because they are good to use in and of 
themselves. (E.g. we don't write "my_tree" because there's no "tree" to 
shadow.) All of these are ugly to some extent, which is to say, they 
cause some small, or not so small, additional cognitive load to the 
reader. We don't use the name "list_" because we like trailing 
underscores! We do it because it avoids the cost of shadowing a built-in.

But in a small function, there's no real cost to shadowing, so why 
bother? Any hypothetical confusion caused is no greater than, and 
probably less than, the increased difficulty in reading any of the 
alternatives.

Either way, we're talking micro-optimizations in readability here. Don't 
get hung up over the choice of a name. If you'd rather never shadow, I'm 
fine with that too. I just think "never shadow" is unnecessarily strict. 
Sometimes shadowing is harmless, and sometimes it's useful.

If you're writing a tutorial for beginners, shadowing a built-in without 
explanation will cause confusion, but for production code, I think it 
reasonable to assume the reader knows Python well enough not to stumble 
over that choice.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#6369

FromChris Angelico <rosuav@gmail.com>
Date2011-05-27 14:10 +1000
Message-ID<mailman.2143.1306469427.9059.python-list@python.org>
In reply to#6368
On Fri, May 27, 2011 at 1:52 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> Because "lst" is not a real word. To native readers of languages derived
> from Latin or Germany, such as English, it is quite a strange "word"
> because it has no vowel. In addition, it looks like 1st (first).

Contrived examples are always awkward; in real examples, there's often
an alternative based on the list's purpose, which can then be used to
offer a name.

> Sometimes shadowing is harmless, and sometimes it's useful.

Agreed on both those halves; and obviously, the times where it's
useful are very much important. I have to say, I do like Python's lack
of keywords for these things; the ability to shadow is a flexibility
that means that, for the most part, new builtins can be added to the
language without breaking existing code.

ChrisA

[toc] | [prev] | [next] | [standalone]


#6417

From"Prasad, Ramit" <ramit.prasad@jpmchase.com>
Date2011-05-27 13:58 -0400
Message-ID<mailman.2158.1306519119.9059.python-list@python.org>
In reply to#6368
>I have to say, I do like Python's lack of keywords for these things

I thought True/False were among the list of keywords in Python 3.x ? Or are those the only keywords?


Ramit



Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423
This communication is for informational purposes only. It is not
intended as an offer or solicitation for the purchase or sale of
any financial instrument or as an official confirmation of any
transaction. All market prices, data and other information are not
warranted as to completeness or accuracy and are subject to change
without notice. Any comments or statements made herein do not
necessarily reflect those of JPMorgan Chase & Co., its subsidiaries
and affiliates.

This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and any
attachments are believed to be free of any virus or other defect
that might affect any computer system into which it is received and
opened, it is the responsibility of the recipient to ensure that it
is virus free and no responsibility is accepted by JPMorgan Chase &
Co., its subsidiaries and affiliates, as applicable, for any loss
or damage arising in any way from its use. If you received this
transmission in error, please immediately contact the sender and
destroy the material in its entirety, whether in electronic or hard
copy format. Thank you.

Please refer to http://www.jpmorgan.com/pages/disclosures for
disclosures relating to European legal entities.

[toc] | [prev] | [next] | [standalone]


#6425

FromEthan Furman <ethan@stoneleaf.us>
Date2011-05-27 11:56 -0700
Message-ID<mailman.2166.1306521804.9059.python-list@python.org>
In reply to#6368
Prasad, Ramit wrote:
>> I have to say, I do like Python's lack of keywords for these things
> 
> I thought True/False were among the list of keywords in Python 3.x ? Or are those the only keywords?

http://docs.python.org/py3k/reference/lexical_analysis.html#keywords

False      class      finally    is         return
None       continue   for        lambda     try
True       def        from       nonlocal   while
and        del        global     not        with
as         elif       if         or         yield
assert     else       import     pass
break      except     in         raise

~Ethan~

[toc] | [prev] | [next] | [standalone]


#6335

FromTerry Reedy <tjreedy@udel.edu>
Date2011-05-26 14:44 -0400
Message-ID<mailman.2125.1306435511.9059.python-list@python.org>
In reply to#6295
On 5/26/2011 3:18 AM, Algis Kabaila wrote:

> And why do you insist on calling an instance of list, "list"? Even a
> human reader will confuse which is which. What you are showing is an
> example how confusing things become when a keyword (list) is
> over-written (with list instance).

(Minor note: 'list' is not a keyword (if it were, it could not be 
over-ridden) but it is a builtin.) You are correct, it is confusing. 
Such usage will also lead to bugs if one ever tries to access the class 
as 'list' later in the program.

Here is a legitimate usage of builtins masking:

import builtins
def list(iterable):
     print('building list from {}: {}'.format(type(iterable),iterable))
     return builtins.list(iterable)

a = list((1,2,3))
b = list({1,2,3})
###
building list from <class 'tuple'>: (1, 2, 3)
building list from <class 'set'>: {1, 2, 3}

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#6339

From"Prasad, Ramit" <ramit.prasad@jpmchase.com>
Date2011-05-26 15:34 -0400
Message-ID<mailman.2128.1306439781.9059.python-list@python.org>
In reply to#6295
>> And why do you insist on calling an instance of list, "list"? Even a
>> human reader will confuse which is which. What you are showing is an
>> example how confusing things become when a keyword (list) is
>> over-written (with list instance).

> (Minor note: 'list' is not a keyword (if it were, it could not be 
>over-ridden) but it is a builtin.) You are correct, it is confusing. 
>Such usage will also lead to bugs if one ever tries to access the >class 
>as 'list' later in the program.


An example of overriding built-ins you *really* do not want to happen (python 2.6.4): 
>>> True = False
>>> True == False
True
>>> print True
False

From what I can tell, this does not work in Python 3.x (at least not in Python 3.1.1)



Ramit



Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423


This communication is for informational purposes only. It is not
intended as an offer or solicitation for the purchase or sale of
any financial instrument or as an official confirmation of any
transaction. All market prices, data and other information are not
warranted as to completeness or accuracy and are subject to change
without notice. Any comments or statements made herein do not
necessarily reflect those of JPMorgan Chase & Co., its subsidiaries
and affiliates.

This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and any
attachments are believed to be free of any virus or other defect
that might affect any computer system into which it is received and
opened, it is the responsibility of the recipient to ensure that it
is virus free and no responsibility is accepted by JPMorgan Chase &
Co., its subsidiaries and affiliates, as applicable, for any loss
or damage arising in any way from its use. If you received this
transmission in error, please immediately contact the sender and
destroy the material in its entirety, whether in electronic or hard
copy format. Thank you.

Please refer to http://www.jpmorgan.com/pages/disclosures for
disclosures relating to European legal entities.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.python


csiph-web