Pourquoi ce code itératif croissant de liste donne-t-il à IndexError: un index d'affectation de liste hors limites?


202

Veuillez considérer le code suivant:

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

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

print j

La sortie (Python 2.6.6 sur Win 7 32 bits) est:

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

Je suppose que c'est quelque chose de simple que je ne comprends pas. Quelqu'un peut-il clarifier cela?


9
appendest la bonne solution pour votre cas d'utilisation, mais il existe une méthode d'insertion sur la liste python qui peut s'insérer directement à la i'ème position dans la liste. j.insert(k, l)
— opensourcegeek

Puis-je demander pourquoi la solution d'OP ne fonctionnerait-elle pas? Pourquoi utiliser append?
— Helen

Réponses:


331

jest une liste vide, mais vous essayez d'écrire dans l'élément [0]dans la première itération, qui n'existe pas encore.

Essayez plutôt ce qui suit pour ajouter un nouvel élément à la fin de la liste:

for l in i:
    j.append(l)

Bien sûr, vous ne feriez jamais cela en pratique si vous ne vouliez que copier une liste existante. Vous feriez juste:

j = list(i)

Sinon, si vous souhaitez utiliser la liste Python comme un tableau dans d'autres langages, vous pouvez pré-créer une liste avec ses éléments définis sur une valeur nulle ( Nonedans l'exemple ci-dessous), et plus tard, écraser les valeurs dans des positions spécifiques:

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

La chose à réaliser est qu'un listobjet ne vous permettra pas d'attribuer une valeur à un index qui n'existe pas.


2
D'accord, merci beaucoup. Je ne savais pas laquelle féliciter car il y a trois réponses presque identiques. C'est à mon avis le plus descriptif. Cheers
— Vladan

Je peux voir que cela peut être très déroutant pour ceux qui viennent d'autres langages comme PHP ou C. j est un type de liste, pas un tableau. Avec le type de liste, je ne pense pas que ce soit en indice. Très déroutant si vous venez d'autres langues.
— Nguai al

@Nguaial Le type de liste est indexable, mais vous ne pouvez accéder qu'aux éléments qui existent déjà - vous ne pouvez pas créer un élément en essayant d'écrire dans un index qui est hors de portée. j [0] = "toto" fonctionnera si la liste contient déjà au moins un élément.
— Steve Mayne

54

Votre autre option consiste à initialiser j:

j = [None] * len(i)

3
Vous souhaitez utiliser len (i) plutôt que max.
— Steve Mayne

26

Faites j.append(l)au lieu j[k] = let évitez kdu tout.


2
Un moyen plus court (plus pythonique?) Pourrait êtrej+=[l]
— Oleh Prypin

2
@BlaXpirit: Cela mettra un fardeau au ramasse-miettes, je pense.
— khachik

2
@BalXpirit: Étant donné que cela ne sauve que quelques caractères (d'autant plus que vous devez ajouter des espaces pour que cela soit acceptable) et que .appendc'est beaucoup plus courant (peut-être pour une raison - je pense que c'est un peu plus facile à comprendre), pas vraiment supérieur de quelque manière que. (Modifier @khachik: Non, +=modifie sur place)

16

Vous pouvez également utiliser une compréhension de liste:

j = [l for l in i]

ou faites-en une copie à l'aide de l'instruction:

j = i[:]

cette deuxième construction est soignée
— javadba

2
Si le seul objectif est de copier la liste, vous pouvez simplement dire j = list (i) Je pense que la question porte davantage sur le comportement des listes que sur le besoin spécifique d'un moyen de copier des éléments.
— Steve Mayne

11
j.append(l)

Évitez également d'utiliser des «L» minuscules car il est facile de les confondre avec les 1


7

Je pense que l' insertion de méthode Python est ce que vous recherchez:

Insère l'élément x à la position i. list.insert (i, x)

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

array.insert(1,20)

print(array)

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

1
Il ne sert à rien d'utiliser insertquand a appendété fourni spécifiquement à cet effet.
— holdenweb

Sur un point d'information, votre code s'imprime en fait [1, 20, 2, 3, 4, 5].
— holdenweb

Vous avez inséré à l'index 1, en déplaçant les index 1 et suivants. La valeur insérée ne finit pas à l'index 2. Iist.insert () n'est vraiment nécessaire que lorsque vous ne voulez pas ajouter l'élément à la fin de la liste; la question ici fait exactement cela, donc list.append () est préférable.
— Martijn Pieters

En fait, pourquoi je réponds à cette question comme ça, je suis aussi surpris: D Je ne sais pas ce que je pensais :) C'est exactement "list.append ()" qui est la réponse acceptée. Je pense que cela aide les gens ou donne une idée pour résoudre leurs problèmes, donc il obtient 5 résultats.
— Mehmet Kagan Kayaalp

5

Vous pouvez utiliser un dictionnaire (similaire à un tableau associatif) pour 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

imprimera:

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

Pour les indices consécutifs commençant à 0, un mappage est généralement la mauvaise structure de données, en particulier lorsque les mappages n'ont pas de découpage ou d'inversion car ils ne sont pas destinés à transmettre un ordre spécifique.
— Martijn Pieters

2

Encore une façon:

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

Dans ce cas, il y jaura un tableau numpy


0

Peut-être avez-vous besoin de prolonger ()

i=[1,3,5,7]
j=[]
j.extend(i)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.