2017-03-14 29 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])) 
相关问题