Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Lists: why is this behavior different for index and slice assignments?

1 view
Skip to first unread message

John Salerno

unread,
Apr 21, 2008, 9:45:53 PM4/21/08
to
Hey all. I've decided I let my Python skills (minor though they were)
slip away so I started reading the new edition of Learning Python to
brush up. I just read about lists again and I'm wondering if someone
could explain what's going on under the hood that makes index and slice
assignments behave differently when assigning an empty list.

For example:

>>> L = [1, 2, 3, 4, 5]
>>> L[0:2] = []
>>> L
[3, 4, 5]

>>> L = [1, 2, 3, 4, 5]
>>> L[0] = []
>>> L
[[], 2, 3, 4, 5]

So the question is, when you assign an empty list to an index, why does
it insert an empty list, but when you assign an empty list to a slice,
it simply deletes the slice?

Thanks!

Michael Torrie

unread,
Apr 21, 2008, 10:10:03 PM4/21/08
to pytho...@python.org
John Salerno wrote:
> So the question is, when you assign an empty list to an index, why does
> it insert an empty list, but when you assign an empty list to a slice,
> it simply deletes the slice?

I would say this is consistent behavior because a list slice is also a
list itself. Whereas a list element is just that. A reference to an
object that can be rebound. In the latter case you are rebinding a
single list item to an empty list.

Steve Holden

unread,
Apr 21, 2008, 10:10:22 PM4/21/08
to pytho...@python.org
Assignment to a list *element* rebinds the single element to the
assigned value. Assignment to a list *slice* has to be of a list, and it
replaces the elements in the slice by assigned elements.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

Duncan Booth

unread,
Apr 22, 2008, 1:45:45 PM4/22/08
to
Steve Holden <st...@holdenweb.com> wrote:

> Assignment to a list *element* rebinds the single element to the
> assigned value. Assignment to a list *slice* has to be of a list, and it
> replaces the elements in the slice by assigned elements.
>

Assignment to a list *slice* just has use an iterable, it doesn't actually
have to be another list.

John Salerno

unread,
Apr 22, 2008, 8:14:13 PM4/22/08
to
Steve Holden wrote:

> Assignment to a list *element* rebinds the single element to the
> assigned value.

Ok, I understand that.

Assignment to a list *slice* has to be of a list [or iterable, as per
Duncan], and it


> replaces the elements in the slice by assigned elements.


I don't understand the second part of that sentence. I'm assuming "it"
refers to the list being assigned, "replaces the elements" is
self-evident, but what does "by assigned elements" refer to? It seems
when you assign a list to a list slice, nothing gets replaced, the slice
just gets deleted.

John Machin

unread,
Apr 22, 2008, 8:30:46 PM4/22/08
to

Deletion occurs *only* in the corner case where there are no "assigned
elements" i.e. only if the RHS list (sequence) is *empty*. Otherwise
there would be no point at all in the language having assignment to a
slice -- del L[0:2] would suffice.

Study these:

>>> L = [1, 2, 3, 4, 5]
>>> L[0:2] = []
>>> L
[3, 4, 5]
>>> L = [1, 2, 3, 4, 5]

>>> L[0:2] = ['whatever']
>>> L
['whatever', 3, 4, 5]


>>> L = [1, 2, 3, 4, 5]

>>> L[0:2] = tuple('foobar')
>>> L
['f', 'o', 'o', 'b', 'a', 'r', 3, 4, 5]
>>>

Matt Nordhoff

unread,
Apr 22, 2008, 8:33:56 PM4/22/08
to pytho...@python.org
John Salerno wrote:
>> replaces the elements in the slice by assigned elements.
>
>
> I don't understand the second part of that sentence. I'm assuming "it"
> refers to the list being assigned, "replaces the elements" is
> self-evident, but what does "by assigned elements" refer to? It seems
> when you assign a list to a list slice, nothing gets replaced, the slice
> just gets deleted.

>>> x = range(5)
>>> x[0:3] = ["a", "b"]
>>> x
['a', 'b', 3, 4]

Here, '= ["a", "b"]' replaces x[0:3] with ["a", "b"]. When you do '=
[]', it replaces them with nothing.
--

John Salerno

unread,
Apr 23, 2008, 11:12:33 PM4/23/08
to
John Machin wrote:

> Deletion occurs *only* in the corner case where there are no "assigned
> elements" i.e. only if the RHS list (sequence) is *empty*.

Oh, it was my understanding that deletion always occurs, even when the
section is being assigned a non-empty value, i.e. delete the slice and
insert new value.

Otherwise
> there would be no point at all in the language having assignment to a
> slice -- del L[0:2] would suffice.

Right, but I'm wondering why a statement like

L[0:2] = []

doesn't assign an empty list as the new element in L. For example:

L = [1, 2, 3, 4, 5]
L[0:2] = []

Why doesn't L now equal [[], 3, 4, 5] as it does with an index assignment?

> >>> L[0:2] = tuple('foobar')
> >>> L
> ['f', 'o', 'o', 'b', 'a', 'r', 3, 4, 5]

Hmm...why doesn't L equal [('f', 'o', 'o', 'b', 'a', 'r'), 3, 4, 5] ?
Shouldn't L be a 4 item list instead of 9?

Terry Reedy

unread,
Apr 24, 2008, 4:56:26 AM4/24/08
to pytho...@python.org

"John Salerno" <john...@gmailNOSPAM.com> wrote in message
news:480ffaae$0$11639$607e...@cv.net...

| John Machin wrote:
|
| > Deletion occurs *only* in the corner case where there are no "assigned
| > elements" i.e. only if the RHS list (sequence) is *empty*.
|
| Oh, it was my understanding that deletion always occurs, even when the
| section is being assigned a non-empty value, i.e. delete the slice and
| insert new value.

Slice replacement means replace the slice with a new slice generated from
the iterable on the left. John meant that deletion only only happens when
the replacement is empty. Yes, deletion always occurs, but usually
addition also occurs, so the net result is replacement rather than just
deletion.

| Otherwise
| > there would be no point at all in the language having assignment to a
| > slice -- del L[0:2] would suffice.
|
| Right, but I'm wondering why a statement like
| L[0:2] = []
| doesn't assign an empty list as the new element in L. For example:

Because, as others already told you, slice replacement is slice
replacement, not item assignment. When you say to replace the slice with
nothing, the deleted slice is replaced with nothing.

L[0:2] = [[]]

says to replace the slice with a slice consisting of one item -- []
That will get you what you are expecting.

| L = [1, 2, 3, 4, 5]
| L[0:2] = []
|
| Why doesn't L now equal [[], 3, 4, 5] as it does with an index
assignment?

See above.

|
| > >>> L[0:2] = tuple('foobar')

L[0:2] = 'foobar' has same effect because s string is an iterable.

| > >>> L
| > ['f', 'o', 'o', 'b', 'a', 'r', 3, 4, 5]
|
| Hmm...why doesn't L equal [('f', 'o', 'o', 'b', 'a', 'r'), 3, 4, 5] ?
| Shouldn't L be a 4 item list instead of 9?

Because you replaced 2 items with 6.

L[0:2] = ['foobar'] will replace 2 with 1, leaving 4

tjr

0 new messages