Warum gibt dieser iterative Code mit wachsender Liste IndexError: Listenzuweisungsindex außerhalb des Bereichs?


194

Bitte beachten Sie den folgenden Code:

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

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

print j

Die Ausgabe (Python 2.6.6 unter Win 7 32-Bit) lautet:

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

Ich denke, es ist etwas Einfaches, das ich nicht verstehe. Kann jemand es klären?


6
appendist die richtige Lösung für Ihren Anwendungsfall, es gibt jedoch eine Einfügemethode für die Python-Liste, die direkt an die i-te Position in der Liste eingefügt werden kann. j.insert(k, l)
opensourcegeek

Darf ich fragen, warum die Lösung von OP nicht funktionieren würde? Warum anhängen?
Helen

Antworten:


317

jist eine leere Liste, aber Sie versuchen, [0]in der ersten Iteration, die noch nicht vorhanden ist , in ein Element zu schreiben .

Versuchen Sie stattdessen Folgendes, um am Ende der Liste ein neues Element hinzuzufügen:

for l in i:
    j.append(l)

Natürlich würden Sie dies in der Praxis niemals tun, wenn Sie nur eine vorhandene Liste kopieren möchten. Sie würden einfach tun:

j = list(i)

Wenn Sie die Python-Liste wie ein Array in anderen Sprachen verwenden möchten, können Sie alternativ eine Liste vorab erstellen, deren Elemente auf einen Nullwert gesetzt sind ( Noneim folgenden Beispiel), und später die Werte an bestimmten Positionen überschreiben:

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

Zu beachten ist, dass Sie mit einem listObjekt einem nicht vorhandenen Index keinen Wert zuweisen können.


2
OK, vielen Dank. Ich wusste nicht, welche ich loben sollte, da es drei fast gleiche Antworten gibt. Das ist meiner Meinung nach am aussagekräftigsten. Prost
Vladan

Ich kann sehen, dass dies für diejenigen, die aus anderen Sprachen wie PHP oder C kommen, sehr verwirrend sein kann. J ist eine Art Liste, kein Array. Beim Listentyp halte ich dies nicht für abonnierbar. Sehr verwirrend, wenn Sie aus anderen Sprachen kommen.
Nguai al

@Nguaial Der Listentyp ist tiefstellbar, Sie können jedoch nur auf bereits vorhandene Elemente zugreifen. Sie können kein Element erstellen, indem Sie versuchen, in einen Index zu schreiben, der außerhalb des Bereichs liegt. j [0] = "foo" funktioniert, wenn die Liste bereits mindestens ein Element enthält.
Steve Mayne

52

Sie können auch Folgendes initialisieren j:

j = [None] * len(i)

3
Sie möchten len (i) anstelle von max.
Steve Mayne

25

Tun Sie j.append(l)statt j[k] = lund vermeiden Sie küberhaupt.


2
Ein kürzerer (pythonischer?) Weg könnte seinj+=[l]
Oleh Prypin

2
@BlaXpirit: Es wird den Müllsammler belasten, denke ich.
Khachik

2
@BalXpirit: Angesichts der Tatsache, dass nur wenige Zeichen gespeichert werden (zumal Sie Leerzeichen hinzufügen müssen, damit es akzeptabel ist) und dass dies .appendweitaus häufiger vorkommt (vielleicht aus einem Grund - ich denke, es ist etwas einfacher zu verstehen), nicht wirklich überlegen in irgendeiner Weise. (Edit @khachik: Nein, +=ändert an Ort und Stelle)

15

Sie können auch ein Listenverständnis verwenden:

j = [l for l in i]

oder machen Sie eine Kopie davon mit der Anweisung:

j = i[:]


2
Wenn das einzige Ziel darin besteht, die Liste zu kopieren, können Sie einfach j = list (i) sagen. Ich denke, die Frage bezieht sich eher auf das Verhalten von Listen als darauf, speziell eine Möglichkeit zum Kopieren von Elementen zu benötigen.
Steve Mayne

10
j.append(l)

Vermeiden Sie auch die Verwendung von "L" in Kleinbuchstaben, da diese leicht mit 1 verwechselt werden können


7

Ich denke, die Python-Methodeneinfügung ist genau das, wonach Sie suchen:

Fügt Element x an Position i ein. list.insert (i, x)

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

array.insert(1,20)

print(array)

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

1
Es macht keinen Sinn zu verwenden, insertwann appendspeziell für diesen Zweck bereitgestellt wurde.
Holdenweb

In Bezug auf Informationen wird Ihr Code tatsächlich gedruckt [1, 20, 2, 3, 4, 5].
Holdenweb

Sie haben bei Index 1 eingefügt und die Indizes 1 und höher verschoben. Der eingefügte Wert endet nicht bei Index 2. Iist.insert () wird nur dann wirklich benötigt, wenn Sie das Element nicht am Ende der Liste hinzufügen möchten. Die Frage hier macht genau das, also ist list.append () vorzuziehen.
Martijn Pieters

Eigentlich, warum ich diese Frage so beantworte, bin ich auch überrascht: D Weiß nicht, was ich dachte :) Dies ist genau "list.append ()", was die akzeptierte Antwort ist. Ich denke, es hilft Menschen oder gibt eine Idee, um ihre Probleme zu lösen, so dass es 5 Treffer bekommt.
Wasser

5

Sie können ein Wörterbuch (ähnlich einem assoziativen Array) für j verwenden

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

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

print j

wird drucken:

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

Für aufeinanderfolgende Anzeigen ab 0 ist eine Zuordnung normalerweise die falsche Datenstruktur, insbesondere wenn Zuordnungen kein Schneiden oder Umkehren aufweisen, da sie keine bestimmte Reihenfolge vermitteln sollen.
Martijn Pieters

2

Noch ein Weg:

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

In diesem Fall handelt jes sich um ein Numpy-Array


0

Vielleicht brauchen Sie verlängern ()

i=[1,3,5,7]
j=[]
j.extend(i)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.