2010-11-01 75 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

相關問題