Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Question about idioms for clearing a list

Reply
Thread Tools

Question about idioms for clearing a list

 
 
Steven Watanabe
Guest
Posts: n/a
 
      01-31-2006
I know that the standard idioms for clearing a list are:

(1) mylist[:] = []
(2) del mylist[:]

I guess I'm not in the "slicing frame of mind", as someone put it, but
can someone explain what the difference is between these and:

(3) mylist = []

Why are (1) and (2) preferred? I think the first two are changing the
list in-place, but why is that better? Isn't the end result the same?

Thanks in advance.
--
Steven.
 
Reply With Quote
 
 
 
 
Diez B. Roggisch
Guest
Posts: n/a
 
      01-31-2006
Steven Watanabe wrote:

> I know that the standard idioms for clearing a list are:
>
> (1) mylist[:] = []
> (2) del mylist[:]
>
> I guess I'm not in the "slicing frame of mind", as someone put it, but
> can someone explain what the difference is between these and:
>
> (3) mylist = []
>
> Why are (1) and (2) preferred? I think the first two are changing the
> list in-place, but why is that better? Isn't the end result the same?


No. Consider this simple example:

class Foo(object):
def __init__(self, all_my_thingies):
self.all_my_thingies = all_my_thingies


things = [1,2,3,4,5]

f = Foo(things)

things = [] # I've been robbed

print f.all_my_thingies # or not?


The reason is that l = [] just rebinds a new object (a list, but it could be
anything) to a name, while l[:] = [] will alter the object _referred_ to by
l. That is a HUGE difference!


Diez



 
Reply With Quote
 
 
 
 
Xavier Morel
Guest
Posts: n/a
 
      01-31-2006
Steven Watanabe wrote:
> I know that the standard idioms for clearing a list are:
>
> (1) mylist[:] = []
> (2) del mylist[:]
>
> I guess I'm not in the "slicing frame of mind", as someone put it, but
> can someone explain what the difference is between these and:
>
> (3) mylist = []
>
> Why are (1) and (2) preferred? I think the first two are changing the
> list in-place, but why is that better? Isn't the end result the same?
>
> Thanks in advance.
> --
> Steven.


The solution (1) and (2) clear the content of the list (replace the
content of the list by an empty list for (1), or delete the content of
the list for (2) while the solution (3) creates a new list and binds the
old name to the new list. This means that you don't actually modify
(clear) the initial list.

Just try it out:

>>> a = range(10)
>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> b = a
>>> b

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> c = a
>>> c

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a.append(10) # assert that a, b and c point to the same list
>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> b

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> c

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> b = []
>>> b

[]
>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> del c[:]
>>> c

[]
>>> a

[]
>>>


Here we can see that using method (3) on b didn't modify the content of
a (even though we asserted that they were the same list).
Using method (2) on c, the other hand, did modify the content of a.

This is because method (3) on b actually created a new list and bound
"b" (as a name) to that new list, without modifying the list "b" used to
be bound to (which is the one "a" and "c" are still bound to).
 
Reply With Quote
 
bearophileHUGS@lycos.com
Guest
Posts: n/a
 
      01-31-2006
Diez B. Roggisch:
> The reason is that l = [] just rebinds a new object (a list, but it could be
> anything) to a name, while l[:] = [] will alter the object _referred_ to by
> l. That is a HUGE difference!


In my programs I have seen that there is another practical difference
between version 1 and 3:
(1) mylist[:] = []
(3) mylist = []
If you create a big mylist again and again many times, the version 1
uses the memory more efficiently (probably less work for the garbage
collector), and the program can be (quite) faster (this is true in some
implementations different from CPython too).

Bye,
bearophile

 
Reply With Quote
 
Will McGugan
Guest
Posts: n/a
 
      02-06-2006
Steven Watanabe wrote:
> I know that the standard idioms for clearing a list are:
>
> (1) mylist[:] = []
> (2) del mylist[:]
>
> I guess I'm not in the "slicing frame of mind", as someone put it, but
> can someone explain what the difference is between these and:
>
> (3) mylist = []
>
> Why are (1) and (2) preferred? I think the first two are changing the
> list in-place, but why is that better? Isn't the end result the same?


I'm wondering why there is no 'clear' for lists. It feels like a common
operation for mutable containers. :-/


Will McGugan

 
Reply With Quote
 
Steve Holden
Guest
Posts: n/a
 
      02-06-2006
Will McGugan wrote:
> Steven Watanabe wrote:
>
>>I know that the standard idioms for clearing a list are:
>>
>> (1) mylist[:] = []
>> (2) del mylist[:]
>>
>>I guess I'm not in the "slicing frame of mind", as someone put it, but
>>can someone explain what the difference is between these and:
>>
>> (3) mylist = []
>>
>>Why are (1) and (2) preferred? I think the first two are changing the
>>list in-place, but why is that better? Isn't the end result the same?

>
>
> I'm wondering why there is no 'clear' for lists. It feels like a common
> operation for mutable containers. :-/
>

Because it's just as easy to create and assign a new empty list (and
have the old unused one garbage collected).

l = []

is all you need!

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      02-06-2006
On Mon, 06 Feb 2006 13:35:10 +0000, Steve Holden wrote:

>> I'm wondering why there is no 'clear' for lists. It feels like a common
>> operation for mutable containers. :-/
>>

> Because it's just as easy to create and assign a new empty list (and
> have the old unused one garbage collected).
>
> l = []
>
> is all you need!


Not so. If that logic were correct, then dicts wouldn't need a clear
method either, because you could just assign a new empty dict with d = {}.

But your own sentence tells us why this is not sufficient: because you
aren't emptying the list, you are reassigning (rebinding) the name. The
old list still exists, and there is no guarantee that it will be garbage
collected, because there is no guarantee that it isn't in use somewhere
else:

L = [0,1,2]
D = {"key": L}
L = [] # rebinds the name L, but the list instance still exists

Perhaps it is arguable that there is no need for a clear method because
L[:] = [] is so easy to do. Personally, while I agree that it is easy, it
is hardly intuitive or obvious, and I too would prefer an explicit clear
method for mutable sequences.


--
Steven.

 
Reply With Quote
 
Dan Sommers
Guest
Posts: n/a
 
      02-06-2006
On Tue, 07 Feb 2006 01:01:43 +1100,
Steven D'Aprano <(E-Mail Removed)> wrote:

> On Mon, 06 Feb 2006 13:35:10 +0000, Steve Holden wrote:
>>> I'm wondering why there is no 'clear' for lists. It feels like a common
>>> operation for mutable containers. :-/
>>>

>> Because it's just as easy to create and assign a new empty list (and
>> have the old unused one garbage collected).
>>
>> l = []
>>
>> is all you need!


> Not so. If that logic were correct, then dicts wouldn't need a clear
> method either, because you could just assign a new empty dict with d = {}.


> But your own sentence tells us why this is not sufficient: because you
> aren't emptying the list, you are reassigning (rebinding) the name. The
> old list still exists, and there is no guarantee that it will be garbage
> collected, because there is no guarantee that it isn't in use somewhere
> else:


> L = [0,1,2]
> D = {"key": L}
> L = [] # rebinds the name L, but the list instance still exists


That is a red herring. Consider this:

L = [object(), object()]
O = L[1]
L = [] # or insert your favorite list-clearing/emptying statement here

What damage is done now that O is still referring to one of the items
that used to be in L?

The trouble begins when references to "the list to which L refers" end
up somewhere else. Then we have to wonder if rebinding L will leave
some other block of code with an outdated list.

Regards,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
 
Reply With Quote
 
Peter Hansen
Guest
Posts: n/a
 
      02-06-2006
Steven D'Aprano wrote:
> Perhaps it is arguable that there is no need for a clear method because
> L[:] = [] is so easy to do. Personally, while I agree that it is easy, it
> is hardly intuitive or obvious, and I too would prefer an explicit clear
> method for mutable sequences.


Possibly another case where "patches are welcome"...

 
Reply With Quote
 
Fredrik Lundh
Guest
Posts: n/a
 
      02-06-2006
Peter Hansen wrote:

> > Perhaps it is arguable that there is no need for a clear method because
> > L[:] = [] is so easy to do. Personally, while I agree that it is easy, it
> > is hardly intuitive or obvious, and I too would prefer an explicit clear
> > method for mutable sequences.

>
> Possibly another case where "patches are welcome"...


so we can have three ways to do the same thing? the right way to
nuke a sequence is to do "del L[:]". this is explained in Python 101.

(del doesn't work on dictionaries)

</F>



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Idioms and Anti-Idioms Question Ben Charrow Python 11 07-04-2009 12:08 AM
Shortening common idioms: bus assignment and 'prev' generation Eli Bendersky VHDL 9 04-07-2006 08:06 AM
RE: Thoughts on new vs traditional idioms Delaney, Timothy C (Timothy) Python 3 03-02-2004 05:13 PM
Thoughts on new vs traditional idioms Raymond Hettinger Python 7 03-01-2004 06:55 PM
Need help with Python class idioms Tad Marko Python 17 01-25-2004 09:38 PM



Advertisments