Replacing selected items in a list in Python

I have a list: mylist = [0, 0, 0, 0, 0]

I only want to replace the selected elements, for example, the first, second and fourth in total, A = 100 .

One way to do this:

 mylist[:2] = [A]*2 mylist[3] = A mylist [100, 100, 0, 100, 0] 

I am looking for one liner or an easier way to do this. A more general and flexible answer is preferable.

+7
source share
6 answers

Especially since you are replacing a significant portion of list , I would do this invariably:

 mylist = [100 if i in (0, 1, 3) else e for i, e in enumerate(mylist)] 

Intentionally in Python, creating a new list is single-line, and an explicit loop is required to mutate list . Usually, if you donโ€™t know which one you want, you want a new list . (In some cases, it is slower or harder, or you have other code that references the same list and should see that it mutated, or something else, therefore "usually", not "always.")

If you want to do this more than once, I would include it in the function, as Volatility suggests:

 def elements_replaced(lst, new_element, indices): return [new_element if i in indices else e for i, e in enumerate(lst)] 

I personally will probably make it a generator so that it gets an iteration instead of returning a list even if I don't need it, simply because I'm so stupid. But if you really need it:

 myiter = (100 if i in (0, 1, 3) else e for i, e in enumerate(mylist)) 

Or:

 def elements_replaced(lst, new_element, indices): for i, e in enumerate(lst): if i in indices: yield new_element else: yield e 
+7
source
 def replace_element(lst, new_element, indices): for i in indices: lst[i] = new_element return lst 

This is definitely a more general solution, but not a one-liner. For example, in your case, you would call:

 mylist = replace_element(mylist, 100, [0, 1, 3]) 
+2
source

Numpy supports this if you don't mind using np.ndarray :

 >>> a = np.zeros(5) >>> a[[0,1,3]] = 100 >>> a array([ 100., 100., 0., 100., 0.]) 
+1
source

Is this what you are looking for? Create a list of indexes that you want to change, and then scroll through the list to change the values.

 els_to_replace = [0, 1, 3] mylist = [0, 0, 0, 0, 0] for index in els_to_replace: mylist[index] = 100 mylist Out[9]: [100, 100, 0, 100, 0] 
0
source

Not a big fan of this, but you can try this (although I think that all of the above is much more concise and easy to read):

 In [22]: from operator import setitem In [23]: mylist = [0, 0, 0, 0, 0] In [24]: indeces_to_replace = [0, 1, 3] In [25]: _ = map(lambda x: setitem(mylist, x, 100), indeces_to_replace) In [26]: mylist Out[26]: [100, 100, 0, 100, 0] 

Besides dubious readability and the need to import, @abarnert pointed out a few additional problems, namely that map still creates an unnecessary list (which is discarded with _ but nonetheless created) and that it wonโ€™t work in Python 3, because that map returns an iterator in Python 3.x. You can use the six module to model map behavior in Python 3.x from Python 2.x and in combination with collections.deque (again, as @abarnert suggested), you can get the same result without creating an extra list in memory , because deque , which can contain a maximum of 0 elements, will discard everything it receives from the map iterator (note that with six , map modeled using itertools.imap ).

Again, there is absolutely no need to ever use this - every solution above / below is better :)

 In [1]: from collections import deque In [2]: from six.moves import map In [3]: from operator import setitem In [4]: mylist = [0, 0, 0, 0, 0] In [5]: indeces_to_replace = [0, 1, 3] In [6]: deque(map(lambda x: setitem(mylist, x, 100), indeces_to_replace), maxlen=0) Out[6]: deque([], maxlen=0) In [7]: mylist Out[7]: [100, 100, 0, 100, 0] 
0
source

I like the list comprehension:

 [100 if index in [1, 4] else 0 for index, x in enumerate(mylist) ] 
0
source

All Articles