Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #52962 > unrolled thread
| Started by | Krishnan Shankar <i.am.songoku@gmail.com> |
|---|---|
| First post | 2013-08-25 09:22 +0530 |
| Last post | 2013-08-25 05:31 +0000 |
| Articles | 2 — 2 participants |
Back to article view | Back to comp.lang.python
List getting extended when assigned to itself Krishnan Shankar <i.am.songoku@gmail.com> - 2013-08-25 09:22 +0530
Re: List getting extended when assigned to itself Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-25 05:31 +0000
| From | Krishnan Shankar <i.am.songoku@gmail.com> |
|---|---|
| Date | 2013-08-25 09:22 +0530 |
| Subject | List getting extended when assigned to itself |
| Message-ID | <mailman.206.1377402755.19984.python-list@python.org> |
[Multipart message — attachments visible in raw view] — view raw
Hi Python Friends, I came across an example which is as below, >>> var = [1, 12, 123, 1234] >>> var [1, 12, 123, 1234] >>> var[:0] [] >>> var[:0] = var >>> var [1, 12, 123, 1234, 1, 12, 123, 1234] >>> Here in var[:0] = var we are assigning an entire list to the beginning of itself. So shouldn't it be something like, [[1, 12, 123, 1234], 1, 12, 123, 1234] It happens when we do the below, >>> var = [1, 12, 123, 1234] >>> var[0] = var >>> var [[...], 12, 123, 1234] >>> Literally var[0] = var and var[:0] = var almost meens the same. But why is the difference in output? Can anyone explain what happens when slicing assignment and direct assignment. Regards, Krishnan
[toc] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-08-25 05:31 +0000 |
| Message-ID | <521996c3$0$29986$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #52962 |
On Sun, 25 Aug 2013 09:22:27 +0530, Krishnan Shankar wrote: > Hi Python Friends, > > I came across an example which is as below, > >>>> var = [1, 12, 123, 1234] >>>> var > [1, 12, 123, 1234] >>>> var[:0] > [] >>>> var[:0] = var >>>> var > [1, 12, 123, 1234, 1, 12, 123, 1234] >>>> >>>> > Here in var[:0] = var we are assigning an entire list to the beginning > of itself. So shouldn't it be something like, > > [[1, 12, 123, 1234], 1, 12, 123, 1234] No, you have misunderstood how slicing works. When you assign to a slice, you *replace* the existing slice with items from the other list: py> L = [1, 2, 3, 4, 5] py> L[2:4] = [None, None, None] py> L [1, 2, None, None, None, 5] Notice that it does not insert the list [None, None, None] as a single item. If the slice you replace is empty, this is equivalent to inserting the items: py> L = [1, 2, 3, 4, 5] py> L[2:2] = [None, None, None] py> L [1, 2, None, None, None, 3, 4, 5] The beginning of the list is just an empty slice: L[:0] means "all the items, starting at the beginning of the list, and finishing *before* index zero". So that makes it an empty slice, and items are inserted after the start of the list but before index zero: py> L = [1, 2, 3, 4, 5] py> L[:0] = [None, None, None] py> L [None, None, None, 1, 2, 3, 4, 5] So assigning to a slice *always* extends. If you try to assign a single value, not inside a list or other iterable, it fails: py> L = [1, 2, 3, 4, 5] py> L[:0] = None Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only assign an iterable Remember that indexes in Python are *before* the item, so when slicing, Python cuts at the vertical lines | as shown below: | a | b | c | d | e | f | g | The vertical lines are numbered 0 through 7, and the slice [2:5] cuts as shown: | a | b | c | d | e | f | g | 0---1---2---3---4---5---6---7 [2:5] => | c | d | e | > It happens when we do the below, > >>>> var = [1, 12, 123, 1234] >>>> var[0] = var >>>> var > [[...], 12, 123, 1234] Here you are *not* assigning to a slice, but setting a single item. The item at position 0 is replaced with the contents of var, which happens to be the same list, but that is just a distraction. It is more clear when you use a different value: py> L = [1, 2, 3, 4, 5] py> L[0] = "something" py> L ['something', 2, 3, 4, 5] > Literally var[0] = var and var[:0] = var almost meens the same. No, they are very different. Even though the difference is a single character, var[:index] and var[index] are very different, no matter what the value of index. The first is a slice ending at index, the second is a single item at index. The same naturally applies to var[index:] as well, which is a slice starting at index. If you wish to insert a sequence as a single object, you have two choices: you can use the list insert() method, or you can wrap the sequence in a list, and then use slice assignment: py> L = [1, 2, 3, 4, 5] py> L[2:4] = [L] py> L [1, 2, [...], 5] -- Steven
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web