"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?
source to share
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 β₯
source to share
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.
source to share