slicing and parallel assignment: inconsistent behaviour??

Hamish Lawson hamish_lawson at yahoo.co.uk
Thu Jul 18 14:59:00 EDT 2002


Toby Donaldson wrote:

>     >>> B = range(10)
>     >>> B[1:5], B[5:10] = B[5:10], B[1:5]
>     >>> B
>     [0, 5, 6, 7, 8, 1, 2, 3, 4, 9]
> 
> This works as I expect. But if I leave out the 10s in the slice
> indices, I get this:
> 
>     >>> A = range(10)
>     >>> A[1:5], A[5:] = A[5:], A[1:5]
>     >>> A
>     [0, 5, 6, 7, 8, 1, 2, 3, 4]

To make things clearer, let's create a list A that has the numbers 0
to 9, and another two lists B1 and B2 each with 10 stars:

	>>> A = range(10)
	>>> A
	[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
	>>> B1 = ['*'] * 10
	>>> B1
	['*', '*', '*', '*', '*', '*', '*', '*', '*', '*']
	>>> B2 = ['*'] * 10
	>>> B2
	['*', '*', '*', '*', '*', '*', '*', '*', '*', '*']

Now we'll modify B1 and B2 by assigning slices from A. We'll take each
slice of A sequentially rather than in parallel.

First we assign A[5:10] to both B1[1:5] and B2[1:5]. Note that the
size of the slice from A has 5 elements, but the size of the LHS
slices for B1 and B2 is only 4. Thus the size of B1 and B2 are both
increased to 11. This increase in size is the crucial factor.

	>>> B1[1:5] = A[5:10]
	>>> B1
	['*', 5, 6, 7, 8, 9, '*', '*', '*', '*', '*']
	>>> B2[1:5] = A[5:10]
	>>> B2
	['*', 5, 6, 7, 8, 9, '*', '*', '*', '*', '*']

Now we come to assign the A[1:5] slice. To see the difference between
assigning to [5:10] and to [5:], we will do the former for B1 and the
latter for B2. Because B1 and B2 are now both 11 elements long,
B1[5:10] is not the same size as B2[5:]. Thus the 4 elements of A[1:5]
replace *5* elements in B1[5:10] but *6* elements in B2[5:] - B1's
last element (B[10]) is not involved.

	>>> B1[5:10] = A[1:5]
	>>> B1
	['*', 5, 6, 7, 8, 1, 2, 3, 4, '*']
	>>> B2[5:] = A[1:5]
	>>> B2
	['*', 5, 6, 7, 8, 1, 2, 3, 4]


Hamish Lawson



More information about the Python-list mailing list