我想在列表中替换一个或多个项目。我的直觉反应是这样的:
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]
它需要就地,所以如果我有其他对象(例如上例中的other_object
)并引用了mylist,那么其他对象将看到更新的值。 (澄清:我不希望对other_object
进行任何更改,因为它是从我维护的代码管理到其他位置。)
这是在Python中最常用的方法吗?如果没有,有更好的方法吗?
答案 0 :(得分:4)
好吧,你自己的解决方案对我来说听起来不错:
mylist[:] = [replacer(item) for item in mylist]
或者你可以用更明确但更详细的方式来做到这一点:
for idx, val in enumerate(mylist):
mylist[idx] = replacer(val)
我可以想象很多其他的方法,但如果我建议他会被烧毁并被禁止地狱
证明other_object
看到了变化:
>>> 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])
欢迎你♥
答案 1 :(得分:2)
你可以直接这样做:
>>> 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]
请注意,在使用原始my_list
的任何位置时,都会通过对其中任何一个名称使用切片分配来更改它:
>>> my_other_list[1][:]=[20,30,40]
>>> my_list
[20, 30, 40]
>>> other_obj
{'eggs': [20, 30, 40]}
更多Ned Batchelder:Facts and myths about Python names and values
根据您的修改:只需更改mylist
inplace,它将在使用mylist
的其他对象中更改(但不会更改mylist
的副本)。您可以使用任何就地修改的方法。
示例:
>>> my_list[:]=['new','inserted','items']
其他两个对象也会改变:
>>> other_obj
{'eggs': ['new', 'inserted', 'items']}
>>> my_other_list
[[1, 2, 3], ['new', 'inserted', 'items']]
请注意这些是否已共享'对象,因为其他程序/进程可以在您不知情的情况下更改名称引用。潜在的偷偷摸摸的错误。