我想知道是否有办法将上面的代码作为就地列表理解或使用map()
(只是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
将无法正确更新。
答案 0 :(得分:0)
这里的杀手案例是,如果m> 2 * k,我们得到 foo 作为输入,它在先前的调用中作为输出产生。这意味着我们不能简单地静态地评估 s 并且在已知元素上轻快地迭代 - 在初始评估时s [max(k,n)]之后的元素是未知的,因此那些 foo 的动态数量。
想象一下, foo 会返回依赖于初始值和随机内容的内容;很容易看到从列表的一个部分到另一个部分的传播不能静态工作。例如,让 foo 附加一个随机的十六进制数字,让我们在原始帖子中尝试这两个想法:
import random
def foo(chr_list):
inventory = "0123456789abcdef"
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']
总而言之,我不认为值得将其纳入单行内容。
答案 1 :(得分: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)]