2017-02-13 36 views
1

比方說,我們有隨機整數將列表中的每個值設置爲對之前值的某些修改?

我希望得到一個新的列表(或者代替改變這個列表),每一個元素都是本身,或前一個元素的列表* 2(取大)

一種方式來做到這一點是:

a = [-1, 0, 5, -2, 1] 

for i in range(1:len(a)): 
    a[i] = max(a[i], a[i-1] * 2) 

#result should be [-1, 0, 5, 10, 20] 

然而,有一個線做一些這方面的創新的方式?是否有一些巧妙的使用lambda,map或iterator來獲得相同的結果?

我嘗試使用zip創建每個值和先前值的對,但只要我們更改一個元素,其餘的zip就沒用了,因爲這些值也不會改變。

+1

https://docs.python.org/3/library/itertools.html#itertools.accumulate – user2357112

回答

2

在Python3:

a = [-1, 0, 5, -2, 1] 
list(itertools.accumulate(a, lambda acc, x: max(2 * acc, x)) 
>>> [-1, 0, 5, 10, 20] 

沒有這樣輕鬆的運氣與Python 2,但:

def agg(acc, x): 
    return acc + [max(2 * acc[-1], x)] 
reduce(agg, a[1:], a[0:1]) 
>>> [-1, 0, 5, 10, 20] 

可以渣土約與定點,使這個多一點賞心悅目的使用方法:

def agg(acc, x): 
    return acc + [max(2 * acc[-1], x)] if acc else [x] 
reduce(agg, a, None) 
>>> [-1, 0, 5, 10, 20] 

關於這種「濫用」reduce()(有時)好的東西是到目前爲止,0有完整的轉換歷史記錄。

1

您可以使用該功能accumulate添加到itertools模塊在Python 3.2或寫自己:

try: 
    from itertools import accumulate # added in Py 3.2 
except ImportError: 
    def accumulate(iterable): 
     """Return running totals (simplified version).""" 
     total = next(iterable) 
     yield total 
     for value in iterable: 
      total += value 
      yield total 
0

如果你打算推出自己的發電機的功能,你可以這樣做:

def twice_if_bigger(iterable): 
    preval = next(iterable) 
    yield preval 
    for value in iterable: 
     preval=max(2*preval,value) 
     yield preval 

a = [-1, 0, 5, -2, 1] 
print([i for i in twice_if_bigger(a.__iter__())]) 

>> [-1, 0, 5, 10, 20] 
相關問題