2013-02-19 97 views
2

this question類似,但不是用一個項目替換另一個項目,而是用一個列表的內容替換任何一個項目的出現。用另一個列表的內容替換列表項目

orig = [ 'a', 'b', 'c', 'd', 'c' ] 
repl = [ 'x', 'y', 'z' ] 
desired = [ 'a', 'b', 'x', 'y', 'z', 'd', 'x', 'y', 'z' ] 

# these are all incorrect, or fail to compile 
[ repl if x == 'c' else x for x in orig ] 
[ [a for a in orig] if x == 'c' else x for x in orig ] 
[ (a for a in orig) if x == 'c' else x for x in orig ] 
[ a for a in orig if x == 'c' else x for x in orig ] 

編輯:清楚我的意思是,以取代所有出現的項目,而不僅僅是第一。 (道歉的人誰沒有涵蓋他們的答案的話。)

回答

4

不同的方法:當我做替代品,我更願意認爲,在字典中的條款。所以我會做類似

>>> orig = [ 'a', 'b', 'c', 'd' ] 
>>> rep = {'c': ['x', 'y', 'z']} 
>>> [i for c in orig for i in rep.get(c, [c])] 
['a', 'b', 'x', 'y', 'z', 'd'] 

其中最後一行是標準拼合成語。

這種方法的一個優點(缺點?)是它會處理多次出現的'c'

[更新:]

或者,如果你喜歡:

>>> from itertools import chain 
>>> list(chain.from_iterable(rep.get(c, [c]) for c in orig)) 
['a', 'b', 'x', 'y', 'z', 'd'] 

在修改後的測試案例:

>>> orig = [ 'a', 'b', 'c', 'd', 'c' ] 
>>> rep = {'c': ['x', 'y', 'z']} 
>>> list(chain.from_iterable(rep.get(c, [c]) for c in orig)) 
['a', 'b', 'x', 'y', 'z', 'd', 'x', 'y', 'z'] 
+3

優勢!我應該在我的問題中明確指出,我需要更換所有實例,而不僅僅是第一個實例。 – moswald 2013-02-19 17:05:51

+0

@DSM - 這是標準拼合成語嗎?一路上我錯過了一個 - 也許是因爲我仍然很難解析它:)。 'itertools.chain'對我來說... – mgilson 2013-02-19 17:08:55

+0

@mgilson:好的,這是標準的* listcomp * flattening成語。 :^) – DSM 2013-02-19 17:10:19

6
>>> orig = [ 'a', 'b', 'c', 'd' ] 
>>> repl = [ 'x', 'y', 'z' ] 
>>> desired = list(orig) #can skip this and just use `orig` if you don't mind modifying it (and it is a list already) 
>>> desired[2:3] = repl 
>>> desired 
['a', 'b', 'x', 'y', 'z', 'd'] 

和當然,如果你不知道'c'是在索引2,你可以使用orig.index('c')找出信息。

+0

刪除了我的答案,因爲它幾乎一樣的你:-) – Abhijit 2013-02-19 16:55:12

+0

@Abhijit - 我似乎有快速的手指今天... – mgilson 2013-02-19 16:57:57

+0

你應該做'期望= list(orig)'使它對初學者更具可讀性,並使任何類型的repl和orig工作的聲明有效 – JBernardo 2013-02-19 17:04:39

2

無需任何幻想:

desired = orig[:2] + repl + orig[3:] 

要找到2您可以搜索orig.index('c')

x = orig.index('c') 
desired = orig[:x] + repl + orig[x+1:] 

如果REPL不是一個列表,就用list(repl)

+1

夠公平(+1)...雖然這隻適用於'repl'類型與'orig'類型相同的情況。如果'repl'是一個生成器,我的答案甚至會工作:-) – mgilson 2013-02-19 16:54:18

+0

@mgilson很容易:'list(repl)'then ... – JBernardo 2013-02-19 16:56:26

0

如果枚舉倒退,你可以將列表擴展爲你因爲你移動的物品已經經歷了枚舉。

>>> orig = [ 'a', 'b', 'c', 'd', 'c' ] 
>>> repl = [ 'x', 'y', 'z' ] 
>>> desired = [ 'a', 'b', 'x', 'y', 'z', 'd', 'x', 'y', 'z' ] 
>>> for i in xrange(len(orig)-1, -1, -1): 
...  if orig[i] == 'c': 
...    orig[i:i+1] = repl 
... 
>>> orig 
['a', 'b', 'x', 'y', 'z', 'd', 'x', 'y', 'z'] 
0

還有一種方法:

>>> import operator 
>>> orig = [ 'a', 'b', 'c', 'd', 'c' ] 
>>> repl = [ 'x', 'y', 'z' ] 
>>> output = [repl if x == 'c' else [x] for x in orig] 
>>> reduce(operator.add, output) 
['a', 'b', 'x', 'y', 'z', 'd', 'x', 'y', 'z'] 
>>> 
相關問題