为什么此迭代列表增长代码使IndexError:列表分配索引超出范围?


194

请考虑以下代码:

i = [1, 2, 3, 5, 8, 13]
j = []
k = 0

for l in i:
    j[k] = l
    k += 1

print j

输出(Win 7 32位上的Python 2.6.6)为:

> Traceback (most recent call last): 
>     j[k] = l IndexError: list assignment index out of range

我想这很简单,我不明白。有人可以清理吗?


6
append是您使用案例的正确解决方案,但是python list上有一个insert方法,可以直接插入到list中的第i个位置。j.insert(k, l)
opensourcegeek

请问,OP的解决方案为什么不起作用?为什么要使用附加?
海伦

Answers:


317

j是一个空列表,但您正在尝试[0]在第一次迭代中写入元素,但该迭代尚不存在。

请尝试以下操作,以将新元素添加到列表的末尾:

for l in i:
    j.append(l)

当然,如果您只想复制一个现有列表,则您永远都不会这样做。您只需:

j = list(i)

另外,如果您想像其他语言的数组一样使用Python列表,则可以预先创建一个列表,并将其元素设置为空值(None在下面的示例中),然后在特定位置覆盖值:

i = [1, 2, 3, 5, 8, 13]
j = [None] * len(i)
#j == [None, None, None, None, None, None]
k = 0

for l in i:
   j[k] = l
   k += 1

要实现的事情是,list对象将不允许您将值分配给不存在的索引。


2
好的,非常感谢。我不知道应该赞扬哪一个,因为几乎有三个答案。我认为这是最具描述性的。干杯
弗拉丹

我可以看到,对于来自其他语言(如PHP或C)的语言,这可能会造成很大的困扰。j是列表的一种,而不是数组。对于列表类型,我不认为这是可以下标的。如果来自其他语言,则非常令人困惑。
Nguai al

@Nguaial列表类型是可下标的,但是您只能访问已经存在的元素-您不能通过尝试写入超出范围的索引来创建元素。如果列表中已经包含至少一个元素,则j [0] =“ foo”将起作用。
史蒂夫·梅恩


25

j.append(l)而不是j[k] = l避免k


2
一种更短的(更Pythonic的)方式可能是j+=[l]
Oleh Prypin 2011年

2
@BlaXpirit:我认为这将增加垃圾收集器的负担。
khachik 2011年

2
@BalXpirit:鉴于它只保存了几个字符(特别是因为您需要添加空格才能使它可以被接受),并且这种.append情况目前为止更为普遍(也许是有原因的-我认为它稍微容易理解),并不是真正的优越以任何方式。(编辑@khachik:否,+=就地修改)

15

您还可以使用列表理解:

j = [l for l in i]

或使用以下语句进行复制:

j = i[:]

第二种结构很整齐
javadba

2
如果唯一的目标是复制列表,则可以简单地说j = list(i)我认为问题更多是关于列表的行为,而不是特别需要复制元素的方法。
史蒂夫·梅恩

10
j.append(l)

还要避免使用小写的“ L”,因为它们很容易与1混淆。


7

我认为您正在寻找Python方法插入项

在位置i处插入元素x。list.insert(i,x)

array = [1,2,3,4,5]

array.insert(1,20)

print(array)

# prints [1,2,20,3,4,5]

1
为此没有专门使用insert何时append提供。
holdenweb

从信息上看,您的代码实际上是打印出来的[1, 20, 2, 3, 4, 5]
holdenweb

您在索引1处插入,置换了索引1及之后的位置。插入的值不会以索引2结尾。仅当您不想在列表的末尾添加项目时才真正需要Iist.insert()。这里的问题正是这样做的,因此list.append()是更可取的。
马丁·彼得斯

其实为什么我也这样回答这个问题,我也感到很惊讶:D不知道我在想什么:)这正是“ list.append()”,它是公认的答案。我认为它可以帮助人们或提出解决问题的想法,因此获得了5次成功。

5

您可以为j使用字典(类似于关联数组)

i = [1, 2, 3, 5, 8, 13]
j = {} #initiate as dictionary
k = 0

for l in i:
    j[k] = l
    k += 1

print j

将打印:

{0: 1, 1: 2, 2: 3, 3: 5, 4: 8, 5: 13}

对于从0开始的连续索引,映射通常是错误的数据结构,尤其是当映射不具有切片或反转时,因为它们不打算传达任何特定顺序。
马丁·彼得斯

2

另一种方式:

j=i[0]
for k in range(1,len(i)):
    j = numpy.vstack([j,i[k]])

在这种情况下j将是一个numpy数组


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.