在满足条件的两个相邻列表元素之间插入元素

时间:2010-11-01 19:45:09

标签: python

在python中,在满足条件的任何两个元素之间插入元素的干净方法是什么?

像这样的电话:

insert_between([1,2,3,4,7,8,9,15,16], 0, lambda x,y: x + 1 != y)

应该产生:

[1,2,3,4,0,7,8,9,0,15,16]

有没有比迭代和附加到第二个列表更好的方法?

3 个答案:

答案 0 :(得分:10)

>>> def insert_between(iterable, fill, cond):
...     iterable = iter(iterable)
...     prev = next(iterable)
...     yield prev
...     for cur in iterable:
...             if cond(prev, cur):
...                     yield fill
...             yield cur
...             prev = cur
...
>>>
>>> list(insert_between([1,2,3,4,7,8,9,15,16], 0, lambda x,y: x + 1 != y))
[1, 2, 3, 4, 0, 7, 8, 9, 0, 15, 16]

这非常有效,因为你无论如何都必须通过列表进行一次传递,这只能传递一次。请注意,它是一个生成器,因此如果一次需要所有值,则需要将其强制转换为列表。

答案 1 :(得分:2)

@ katrielalex的版本可能是最有效的方式,无论是在时间还是内存方面。这是一个返回新列表而不是迭代器的类似版本。

def insert_between(items, insert_item, compare):
    result = items[:1]
    prev = result[0]
    for item in items[1:]:
        if not compare(prev, item):
            result.append(insert_item)
        result.append(item)
        prev = item
    return result

如果您需要修改列表,而不使用两个列表的内存,则可以执行切片分配。我有点不喜欢在这里使用索引和while循环,但是因为我们正在修改列表,所以在这种情况下它似乎是最简单的方法。这将会变慢,特别是对于大型列表,但您也可以使用大型列表保存最多的内存。

def insert_between(items, insert_item, compare):
    i = 1
    while i < len(items):
        if not compare(items[i-1], items[i]):
            items[i:i] = [insert_item]
            i += 1
        i += 1
    return items

答案 2 :(得分:1)

可以使用lambda函数轻松完成并减少

l=[1, 2, 3, 4, 7, 8, 9, 15, 16]
f = lambda l, i: l+[0,i] if l and l[-1]+1!=i else l+[i]
print reduce(f, l, [])
[1, 2, 3, 4, 0, 7, 8, 9, 0, 15, 16]
相关问题