2017-05-02 42 views
3

我想在列表中替換一個或多個項目。我的直覺反應是這樣的:替換列表中的一個或多個項目的「Pythonic」方法

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?如果不是,還有更好的方法嗎?

+1

慣用的方法是不做到位,而是返回一個新的對象,你可以傳遞給關心它的事物 – Daenyth

+2

不,這是*功能*的方式,而不是慣用的,我很想做,但我不能在這種情況下。 –

+0

mylist = [mylist中項目的替換項(item)] – Muposat

回答

4

好,自己的解決方案聽起來很細對我說:

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

,或者你可以做一個更加明確,但冗長的方式:

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

我可以想像很多其他方式,但我會被燒燬,並禁止地獄,如果我建議他們


證明other_object小號EES的變化:

>>> 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]) 

歡迎您♥

+0

這些方法都不會更新'other_object',就像請求的OP一樣。 – blacksite

+3

@not_a_robot這些方法會改變列表,這是'other_object'包含的列表。代碼不必觸摸'other_object'就可以將變化反映在那裏。 –

+0

@not_a_robot你爲什麼這麼說? – fedeisas

2

您可以直接做到這一點:任何地方原來my_list使用,它是通過改變使用切片分配

>>> 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_other_list[1][:]=[20,30,40] 
>>> my_list 
[20, 30, 40] 
>>> other_obj 
{'eggs': [20, 30, 40]} 

更多的斯內德爾德:Facts and myths about Python names and values


根據您的編輯:只要改變mylist就地並在mylist使用(但不是mylist副本),它會在其他物體發生變化。您可以使用任何可以修改的方法。

例子:

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

另外兩個物體變化得:

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

只是要小心,如果這些是「共享」對象,因爲其他程序/進程可以改變在您不知情的名稱引用。潛在的偷偷摸摸的錯誤。

相關問題