2010-11-01 60 views
3

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

有没有更好的办法,而不是重复和追加到第二个列表?

+1

你确定条件应该给该输出做什么? 4 + 1!= 7. – katrielalex 2010-11-01 19:50:00

+0

对不起,改正了。 – 2010-11-01 19:51:46

+0

用list.insert(value,index)插入到位? – 2010-11-01 19:56:44

回答

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] 

这是非常有效率,你会得到,因为你将不得不做出一次通过列表无论如何,这使得只有一个通行证。注意它是一个生成器,所以如果你一次需要所有的值,你需要将它转换为列表。

+0

这看起来不错,谢谢 – 2010-11-01 19:54:15

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

我觉得奇怪的是,'reduce'会得到更长的列表。我希望'reduce'能够[将iterable减少为单个值](https://docs.python.org/2/library/functions.html#reduce)。 – Jon 2014-08-05 08:07:44

+0

这就是说...这非常有用! – Jon 2014-08-05 08:20:43

相关问题