"Pythonic" way to replace one or more elements in a list, in place

I want to replace one or more items in a list, in place. My gut reaction would be something like this:

mylist = [...]
other_object = dict(spam='eggs', a_list=mylist)

def replacer(item):
   ... contents not shown, returns a replacement ...

mylist[:] = [replacer(item) for item in mylist]

      

It needs to be in place, so if I have other objects (like other_object

in the example above) referencing mylist, then those other objects will see the updated value. (Clarification: I do not want to require any changes to other_object

, because it is managed elsewhere from the code I maintain.)

Is this the most idiomatic way to do it in Python? If not, is there a better way?

+3


source to share


2 answers


ok your own solution sounds pretty good to me:

mylist[:] = [replacer(item) for item in mylist]

      

or you can do it in a more explicit but correct way:

for idx, val in enumerate(mylist):
    mylist[idx] = replacer(val)

      

I can imagine many other ways, but I would be burned and banned to hell if I offer them πŸ”₯πŸ”₯πŸ”₯




Demonstrating other_object

seeing change:

>>> def replacer(x):
...     return x+2
... 
>>> mylist = [1,2,3]
>>> other_object = dict(spam='eggs', a_list=mylist)
>>> mylist[:] = [replacer(item) for item in mylist]
>>> mylist, other_object['a_list']
([3, 4, 5], [3, 4, 5])

      

Welcome β™₯

+4


source


You can do it directly:

>>> my_list=[1,2,3]
>>> other_obj={'eggs':my_list}
>>> my_other_list=[[1,2,3],my_list]
>>> other_obj['eggs'][:]=[e+2 for e in other_obj['eggs']]
>>> other_obj
{'eggs': [3, 4, 5]}
>>> my_other_list
[[1, 2, 3], [3, 4, 5]]
>>> my_list
[3, 4, 5]

      

Note that wherever the original is used my_list

, it is modified by slice assignment for any of these names:

>>> my_other_list[1][:]=[20,30,40]
>>> my_list
[20, 30, 40]
>>> other_obj
{'eggs': [20, 30, 40]}

      

More in Ned Batchelder: Facts and Myths About Python Names and Values




Based on your edit: just change mylist

inplace and change in other objects where used mylist

(but not copy mylist

). You can use any method that does site modification.

Example:

>>> my_list[:]=['new','inserted','items']

      

The other two objects change too:

>>> other_obj
{'eggs': ['new', 'inserted', 'items']}
>>> my_other_list
[[1, 2, 3], ['new', 'inserted', 'items']]

      

Just be careful if they are "shared" objects, as other programs / processes can change the name reference without your knowledge. Potentially sneaky mistakes.

+2


source







All Articles