2

I want to change ,multiple values in a list, for example, every multiple of 2. Using slicing. my logic is:

list = [0] * 10
list[::2] = 1

However, I get an error message: " must assign iterable to extended slice" Can someone explain the error and also the correct logic to preform something like this? Thanks.

2 Answers2

2

When you assign to a slice of a list, you need the assignment to be a list of the same length as the slice. For your example, assign a list of 5 ones:

l = [0] * 10
l[::2] = [1] *5

It isn't obvious why in this example, but if you think about it, you were doing:

l[3:6] = 2

Obviously that doesn't make sense. You are trying to assign an int to a list, which won't work. l[::2] is just another way to slice a list, so you must assign a list to it.

In the future, don't name your lists "list" because doing so overrides the builtin list() function.

Joe Iddon
  • 20,101
  • 7
  • 33
  • 54
Sam Craig
  • 875
  • 5
  • 16
  • 1
    *l[::2] is just another way to slice a list, so you must assign a list to it.* Well, not really. When this is on the left hand of an assignment statement it's hooking into `list.__setitem__`. That could be implemented to accept a scalar. – wim Nov 27 '17 at 20:04
  • @wim it obviously isn't implemented that way though. We are working with the Python built ins, not some library which you could change. – Sam Craig Nov 27 '17 at 20:05
  • 3
    It's still incorrect statement regardless. You can for example assign the string 'hello' here. – wim Nov 27 '17 at 20:07
2

my_list[::2] has 10//2 (=5) elements, so the right part of the assignment should have 10//2 elements as well:

>>> my_list = [0] * 10
>>> my_list[::2] = [1]*(10//2)
>>> my_list
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]

Or you could use numpy with broadcasting:

>>> import numpy as np
>>> a = np.zeros(10)
>>> a
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
>>> a[::2] = 1
>>> a
array([ 1.,  0.,  1.,  0.,  1.,  0.,  1.,  0.,  1.,  0.])
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124