3

how can i programaticaly replace one item in a list with two or more? I'm doing it with splits and indexes, and it looks very un-python.

I'm wishing something like this exists:

values = [ "a", "b", "old", "c" ]
[ yield ["new1", "new2"] if item == "old" else item for item in values ]
// return [ "a", "b", "new1", "new2", "c" ]
4

4 回答 4

12

最好的方法是使用itertools.chain.from_iterable

itertools.chain.from_iterable(
  ("new1", "new2") if item == "old" else (item, ) for item in values)

您面临的“每个项目多个项目”问题通过制作一个嵌套列表,然后将其展开来解决。通过制作所有项目元组(我们只想要一个的单项元组),我们可以实现这一点。

当然,如果您需要一个列表而不是迭代器,请使用对list().

于 2013-08-28T21:38:39.757 回答
2

我认为你的想法是正确的。然而,列表推导并不总是很合适。

这是使用列表连接的解决方案:

values = [ 'a', 'b', 'old', 'c' ]

def sub1(values, old, new):
    newvalues = []
    for item in values:
        if item == old:
            newvalues += new
        else:
            newvalues += [item]
    return newvalues

print sub1(values, 'old', ['new1', 'new2'])

这里使用发电机:

def sub2(values, old, new):
    for item in values:
        if item == old:
            for i in new:
                yield i
        else:
            yield item

for i in sub2(values, 'old', ['new1', 'new2']):
    print i
于 2013-08-28T21:51:20.357 回答
1

这是 OP在这里要求的多个值的通用*解决方案:

subs = {'old':("new1", "new2"), 'cabbage':('ham','and','eggs')}
itertools.chain.from_iterable(
  subs[item] if item in subs else (item, ) for item in values)

使用基于附加的方法也不会变得更容易或更难:

def sub1(values, subs):
    newvalues = []
    for item in values:
        if item in subs:
            newvalues += subs[item]
        else:
            newvalues += [item]
    return newvalues

*如果您的旧项目不可散列,那么这将不起作用,您需要使它们可散列或找出另一个数据结构。比起写出相等性测试,你仍然会更喜欢它。

于 2013-08-28T22:27:03.370 回答
-1

好的。功能更强大,但我不确定这是否真的更“Pythonic”:

reduce(operator.add, [ [x] if x != 'old' else ['new1','new2']  for x in values ] )

与另一个答案实际上相同,除了 reduce 而不是 itertools。

Reduce 是一个标准的函数式编程习惯,所以它的作用应该更明显。

itertools.chain.from_iterable 很酷,但有点晦涩。

于 2013-08-29T01:37:08.637 回答