Skip to main content
 首页 » 编程设计

python之为什么这个元胞自动机代码在 Python 3.x 中工作得很好,但在 Python 2.x 中却不行

2025年05月04日11mate10pro

我有以下代码(生成一个基本元胞自动机):

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 中会产生这个 Index 错误?

请您参考如下方法:

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] 

为了更清楚地展示这一点,您可以在解释器 session 中对此进行测试。 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 .