简体   繁体   English

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

[英]Insert an element between two adjacent list elements which meet a condition

In python, what's a clean way to insert an element between any two elements that meet a condition? 在python中,在满足条件的任何两个元素之间插入元素的干净方法是什么?

A call like: 像这样的电话:

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

should produce: 应该产生:

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

Is there a better way than to iterate and append to second list? 有没有比迭代和附加到第二个列表更好的方法?

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

This is pretty much as efficient as you'll get, because you're going to have to make one pass through the list anyway and this makes only one pass. 这非常有效,因为你无论如何都必须在列表中进行一次传递,这只能传递一次。 Notice that it is a generator, so you need to cast it to a list if you need all the values at once. 请注意,它是一个生成器,因此如果您需要一次所有值,则需要将其强制转换为列表。

@katrielalex's version is probably the most efficient way to do it, both in terms of time and memory. @ katrielalex的版本可能是最有效的方式,无论是在时间还是内存方面。 Here is a similar version that returns a new list rather than an iterator. 这是一个返回新列表而不是迭代器的类似版本。

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

If you need to modify a list in place, without using the memory for two lists, you can do slice assignment. 如果需要在不使用两个列表的内存的情况下修改列表,则可以执行切片分配。 I kind of dislike using the index and while loop here, but since we're modifying the list as we go, it seems the simplest way in this case. 我有点不喜欢while这里使用索引和while循环,但是因为我们正在修改列表,所以在这种情况下它似乎是最简单的方法。 This will be slower, especially with large lists, but you'll also save the most memory with large lists. 这将更慢,尤其是对于大型列表,但您还将使用大型列表保存最多的内存。

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

Can be done easily using lambda function and reduce 可以使用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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM