我有以下代码(生成基本元胞自动机):
def cellular_automaton(init_string,pattern,gens):
values=[128,64,32,16,8,4,2,1]
pattern_list=[]
k=0
while k<len(values):
if values[k]+sum(pattern_list)<=pattern:
pattern_list.append(values[k])
k=k+1
i=0
j=0
b=[]
f=''
pos_init=[0,1,0]
pos_interm=[]
pos_init=[[n,n+1,n] for n in range(len(init_string)-1)]
pos_interm.append(pos_init)
pos_interm[-1][-1].append(len(init_string)-1)
pos_interm[-1][-1].append(0)
pos_interm[0][0].insert(0,len(init_string)-1)
pos_interm2=[val for subl in pos_interm for val in subl]
pos=[val for subl in pos_interm2 for val in subl]
b.append(pos)
while j<gens:
pos=[i+len(init_string) for i in pos]
b.append(pos)
j=j+1
c=[val for subl in b for val in subl]
while i<len(c):
if init_string[c[i]]=='.' and init_string[c[i+1]]=='.' and init_string[c[i+2]]=='.':
if 1 in pattern_list:
init_string=init_string+'x'
else:
init_string=init_string+'.'
elif init_string[c[i]]=='.' and init_string[c[i+1]]=='.' and init_string[c[i+2]]=='x':
if 2 in pattern_list:
init_string=init_string+'x'
else:
init_string=init_string+'.'
elif init_string[c[i]]=='.' and init_string[c[i+1]]=='x' and init_string[c[i+2]]=='.':
if 4 in pattern_list:
init_string=init_string+'x'
else:
init_string=init_string+'.'
elif init_string[c[i]]=='.' and init_string[c[i+1]]=='x' and init_string[c[i+2]]=='x':
if 8 in pattern_list:
init_string=init_string+'x'
else:
init_string=init_string+'.'
elif init_string[c[i]]=='x' and init_string[c[i+1]]=='.' and init_string[c[i+2]]=='.':
if 16 in pattern_list:
init_string=init_string+'x'
else:
init_string=init_string+'.'
elif init_string[c[i]]=='x' and init_string[c[i+1]]=='.' and init_string[c[i+2]]=='x':
if 32 in pattern_list:
init_string=init_string+'x'
else:
init_string=init_string+'.'
elif init_string[c[i]]=='x' and init_string[c[i+1]]=='x' and init_string[c[i+2]]=='.':
if 64 in pattern_list:
init_string=init_string+'x'
else:
init_string=init_string+'.'
elif init_string[c[i]]=='x' and init_string[c[i+1]]=='x' and init_string[c[i+2]]=='x':
if 128 in pattern_list:
init_string=init_string+'x'
else:
init_string=init_string+'.'
i=i+3
return init_string[(len(pos_interm2)+1)*-2:(len(pos_interm2)+1)*-1]
产生的输出如下:
print cellular_automaton('.x.x.x.x.', 17, 2)
此代码在Python 3.3.2中运行良好,但在Python 2.7中产生了“字符串索引超出范围”错误:
Traceback (most recent call last):
File "vm_main.py", line 33, in <module>
import main
File "/tmp/vmuser_trwqmlfqgq/main.py", line 143, in <module>
print cellular_automaton('.x.x.x.x.', 17, 2)
File "/tmp/vmuser_trwqmlfqgq/main.py", line 95, in cellular_automaton
if init_string[c[i]]=='.' and init_string[c[i+1]]=='.' and init_string[c[i+2]]=='.':
IndexError: string index out of range
我对Py2和Py3之间的差异并不是那么熟悉,所以如果有人能帮助我找到使其在Python 2.7中运行的方法,我会很高兴。为什么它会在Py2中产生这个索引错误?
答案 0 :(得分:11)
pos=[i+len(init_string) for i in pos]
在Python 2中,这会泄漏i
的最后一个值,覆盖原始初始值0
。因此,Python 2将从索引8开始,稍后将导致索引错误。
要解决此问题,只需为该变量指定一个不同的名称:
pos=[k+len(init_string) for k in pos]
为了展示更清楚的示例,您可以在解释器会话中对此进行测试。 Python 3将正确保留i
的原始值:
>>> i = 0
>>> [i for i in range(5)]
[0, 1, 2, 3, 4]
>>> i
0
然而,Python 2将保持循环的最后一个值在列表理解中:
>>> i = 0
>>> [i for i in range(5)]
[0, 1, 2, 3, 4]
>>> i
4
有关此更改的详情,请参阅this answer。