用另一个列表的内容替换列表项目
问题描述:
与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 ]
编辑:清楚我的意思是,以取代所有出现的项目,而不仅仅是第一。 (道歉的人谁没有涵盖他们的答案的话。)
答
不同的方法:当我做替代品,我更愿意认为,在字典中的条款。所以我会做类似
>>> 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']
答
>>> 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')
找出信息。
答
无需任何幻想:
desired = orig[:2] + repl + orig[3:]
要找到2
您可以搜索orig.index('c')
。
x = orig.index('c')
desired = orig[:x] + repl + orig[x+1:]
如果REPL不是一个列表,就用list(repl)
答
如果枚举倒退,你可以将列表扩展为你因为你移动的物品已经经历了枚举。
>>> 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']
答
还有一种方法:
>>> 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']
>>>
优势!我应该在我的问题中明确指出,我需要更换所有实例,而不仅仅是第一个实例。 – moswald 2013-02-19 17:05:51
@DSM - 这是标准拼合成语吗?一路上我错过了一个 - 也许是因为我仍然很难解析它:)。 'itertools.chain'对我来说... – mgilson 2013-02-19 17:08:55
@mgilson:好的,这是标准的* listcomp * flattening成语。 :^) – DSM 2013-02-19 17:10:19