2016-11-28 51 views
0

我想知道是否有一種方法可以做到上面的代碼爲就地列表理解或使用map()(只是for循環):就地for循環就地列表解析

s = [''] * n 
s[0:k] = ['X'] * k 
for i in range(k,m): 
    s[i] = foo(s[i-k:i]) 

如果我做的:

s = [''] * n 
s[0:k] = ['X'] * k 
s = [foo(s[i-k:i]) for i in range(k,m)] 

s將無法​​正確更新。

+8

它已經足夠令人費解 – wim

+0

取代原單切片你意識到'ik'將在年初負值,因爲'K> 0'和' i> = 0',會導致索引'[ik:i]'沒有意義(空列表) – Uriel

+0

@UrielEli對不起,我編輯 – ViniciusArruda

回答

0

這裏的殺手級案例是,如果m> 2 * k,我們得到foo將以前產生的輸出作爲輸入。這意味着我們不能簡單地靜態評估s並且愉快地重複遍歷已知元素 - s [max(k,n)]之後的元素在初始評估中未知,因此將其中的一個添加到foo是一個動態數量。

想象一下,foo返回的東西取決於初始值和隨機的東西;很容易看到從列表的一部分傳播到另一部分不能靜態工作。舉例來說,有添加一個隨機的十六進制數字,讓我們嘗試在原發布這兩個觀念:

import random 
def foo(chr_list): 
    inventory = "abcdef" 
    return chr_list[0] + random.choice(inventory) 

k = 3 
m = 10 
n = 16 
s = [''] * n 
s[0:k] = ['X'] * k 

print "1 s init", s 
for i in range(k,m): 
    s[i] = foo(s[i-k:i]) 
print "1 s done", s 
print 

s = [''] * n 
s[0:k] = ['X'] * k 
print "2 s init", s 
s = [foo(s[i-k:i]) for i in range(k,m)] 
print "2 s done", s 

輸出:

1 s init ['X', 'X', 'X', '', '', '', '', '', '', '', '', '', '', '', '', ''] 
1 s done ['X', 'X', 'X', 'X7', 'Xd', 'X9', 'X74', 'Xd6', 'X9d', 'X741', '', '', '', '', '', ''] 

2 s init ['X', 'X', 'X', '', '', '', '', '', '', '', '', '', '', '', '', ''] 
2 s done ['X8', 'X2', 'X9', 'f', 'd', '0', '7'] 

總之,我不認爲這是價值把這個放在一個單線上。

0

正如評論提到的,列表理解總是會創建一個新列表。如果您將列表理解的結果直接分配給它,您的原始列表將會消失。

你可以用列表解析的結果如下

# compact initialization into 1 line 
s = ['X']*k + [''] * (n-k) 
# replace slice of list s from k to m 
s[k:m] = [foo(s[i-k:i]) for i in range(k,m)]