简体   繁体   English

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

[英]“Pythonic” way of replacing one or more items 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 that if I have other objects (eg other_object in the above example) with a reference to mylist, then those other objects will see the updated value. 它需要就地,所以如果我有其他对象(例如上例中的other_object )并引用了mylist,那么其他对象将看到更新的值。 (Clarification: I do not want to require any changes to other_object because it is managed elsewhere from the code I maintain.) (澄清:我不想进行任何更改other_object ,因为它是从我维护代码的其他地方进行管理。)

Is this the most idiomatic way to do it in Python? 这是在Python中最常用的方式吗? If not, is there a better way? 如果没有,有更好的方法吗?

well, your own solution sounds pretty fine to me: 好吧,你自己的解决方案对我来说听起来很不错:

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

or you can do it in a more explicit but verbose way: 或者你可以用更明确但冗长的方式来做到这一点:

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

I can imagine many other ways, but I would be burnt and banned to hell if I suggest them 🔥🔥🔥 我可以想象很多其他的方法,但如果我建议他,我会被烧毁并被禁止地狱🔥🔥🔥


Demonstrating that other_object sees the change: 证明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])

you're welcome ♥ 你是受欢迎的♥

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]

Notice that anywhere the original my_list is used, it is changed by using a slice assignment to any one of those names: 请注意,在使用原始my_list任何位置,都会通过对任何一个名称使用切片分配来更改它:

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

More at Ned Batchelder: Facts and myths about Python names and values 更多Ned Batchelder: 关于Python名称和价值观的事实和神话


Based on your edit: Just change mylist inplace and it will change in the other objects where mylist is used (but not a copy of mylist ). 基于您的编辑:只需更改地址中的mylist ,它将在使用mylist的其他对象(但不是mylist的副本)中更改。 You can use any method that does in place 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 beware if these are 'shared' objects since other programs / processes can change the name reference without your knowledge. 请注意这些是否为“共享”对象,因为其他程序/进程可能会在您不知情的情况下更改名称引用。 Potentially sneaky bugs. 可能是鬼鬼祟祟的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM