2013-09-28 36 views
1

我有以下代碼(產生初等元胞自動):爲什麼這段代碼在Python 3.3中工作得很好,但在Python 2.7中卻不能?

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和PY 3之間的差異,所以我會很高興,如果任何人都可以^ h elp我也發現要做什麼才能使它在Python 2.7中工作。它如何在Py2中產生這個索引錯誤?

+3

'print cellular_automaton('。x.x.x.x',17,2)'< - 這不是有效的Python 3語法。 – poke

+1

把pdb拿出來弄明白 –

+0

'print'是3.x中的一個函數 – rlms

回答

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

+0

謝謝你,戳。這非常有幫助! – Revilo79

+0

非常好。喜歡從意想不到的問題中學習這樣的東西。 – beroe

+0

@poke所以在Python3.X列表壓縮有它自己的命名空間(ture for dict compression too too)**? –

相關問題