“Pythonic”替换列表中的一个或多个项目的方法

时间:2017-05-02 18:35:21

标签: python python-2.7 list

我想在列表中替换一个或多个项目。我的直觉反应是这样的:

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中最常用的方法吗?如果没有,有更好的方法吗?

2 个答案:

答案 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']]

请注意这些是否已共享'对象,因为其他程序/进程可以在您不知情的情况下更改名称引用。潜在的偷偷摸摸的错误。