2017-03-14 30 views
-1

我正在研究一個簡單的左循環移位函數(即餵它[1,2,3]並返回[[1,2,3],[2,3,1],[3,1,2]])。如果我使用此版本的代碼:爲什麼此列表分配索引超出範圍?

def left_shifts(L): 
    if len(L) == 0: 
     M = [] 
    elif len(L) == 1: 
     M = deepcopy(L) 
    else: 
     M = [len(L)] 
     M[0] = L 
     for i in range(1,len(L)): 
      M[i] = (L[i:] + L[:i]) 

    return M 

print (left_shifts([1,2,3,4,5])) 

我收到一個錯誤,列表分配索引超出範圍。但是,如果我只是調整到這一點:

def left_shifts(L): 
    if len(L) == 0: 
     M = [] 
    elif len(L) == 1: 
     M = deepcopy(L) 
    else: 
     M = [len(L)] 
     M[0] = L 
     for i in range(1,len(L)): 
      M.append((L[i:] + L[:i])) #changed line 

    return M 

print (left_shifts([1,2,3,4,5])) 

它工作正常。我的問題是:爲什麼上面的代碼會產生這個錯誤?我所做的只是將兩個列表加在一起,並將其分配給另一個列表中的一個元素,我認爲這將是合法的。

+0

@ TigerhawkT3:這不是適用的。我認爲OP認爲'M = [len(L)]'創建了一個'len(L)'元素列表,在這一點上認爲存在'M [1]'並不是不合理的。 –

+0

@MartijnPieters - 答案解釋了確切的問題。我認爲這是一個精確的重複。 – TigerhawkT3

+0

@ TigerhawkT3:它不包含'[integer]',然後期待'integer'數量的元素存在。 –

回答

1

M = [len(L)]創建了一個元素,整數列表:

>>> L = [1, 2, 3] 
>>> len(L) 
3 
>>> [len(L)] 
[3] 

這就是爲什麼M[1]不存在;您有一個長度爲1的列表,因此只有索引0存在。

如果您期望創建一個列表與len(L)元素,你需要用乘法:

M = [None] * len(L) 

這將創建len(L)引用None列表。但是,不要使用列表乘法來表示可變對象; [...] * N不會創建內容的副本;你會得到相同內容的N引用。當這些內容本身是可變的時,這很重要。

不是說你的代碼需要這麼複雜。只需使用列表理解:

def left_shifts(L): 
    return [L[i:] + L[:i] for i in range(len(L))] 

演示:

>>> def left_shifts(L): 
...  return [L[i:] + L[:i] for i in range(len(L))] 
... 
>>> left_shifts([1, 2, 3]) 
[[1, 2, 3], [2, 3, 1], [3, 1, 2]] 
+0

」在這種情況下,索引0到41應該設置爲什麼?「 - 有些語言允許稀疏數組,並且它們通常使用空值(或0或垃圾數據) 。 – TigerhawkT3

+0

@ TigerhawkT3:Python也有一些稀疏的數組實現,但是Python沒有列出這樣一個野獸。稀疏數組是特殊的結構,不適合像'list'這樣的普通序列主幹。:-) –

+0

@ TigerhawkT3:I因爲我現在很確定OP意味着創建一個'len(L)'元素列表。 –

1

我想解釋這一點的最好辦法就是通過稍微修改代碼:

def left_shifts(L): 
    if len(L) == 0: 
     M = [] 
    elif len(L) == 1: 
     M = deepcopy(L) 
    else: 
     M = [len(L)] 
     print(M) 
    return M 

print (left_shifts([1,2,3,4,5])) 

所以我改成了打印你剛剛分配給M的東西。

它輸出:

[5] 

你只是在它使一個陣列,5號...在Python數組的定義不以這種方式工作。 Python使用獨特的語法。另外,[]定義了一個列表,而不是一個數組。

只需使用追加功能。

新代碼:

def left_shifts(L): 
    if len(L) == 0: 
     M = [] 
    elif len(L) == 1: 
     M = deepcopy(L) 
    else: 
     M = [] 
     M.append(L) 
     for i in range(1,len(L)): 
      M.append((L[i:] + L[:i])) #changed line 

    return M 

print (left_shifts([1,2,3,4,5])) 
相關問題