[英]In-place for loop to in-place list comprehension
我想知道是否有一种方法可以将上面的代码作为就地列表理解或使用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
将无法正确更新。
这里的杀手case是,如果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']
总而言之,我认为将其放在一线之内是不值得的 。
正如评论所提到的,列表理解总是创建一个新列表。 如果直接将列表理解的结果分配给原始列表,则原始列表将消失。
您可以使用列表理解的结果替换原始列表的切片,如下所示
# 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)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.