248

I tried writing some code like:

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

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

But I get an error message that says IndexError: list assignment index out of range, referring to the j[k] = l line of code. Why does this occur? How can I fix it?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Vladan
  • 2,793
  • 5
  • 19
  • 15
  • 10
    `append` is the right solution for your use case, however there's an insert method on python list which can insert directly to the i'th position in list. `j.insert(k, l)` – opensourcegeek Sep 30 '15 at 08:46
  • May I ask, why would not OP's solution work? Why use append? – Helen Jun 10 '18 at 16:01

9 Answers9

394

j is an empty list, but you're attempting to write to element [0] in the first iteration, which doesn't exist yet.

Try the following instead, to add a new element to the end of the list:

for l in i:
    j.append(l)

Of course, you'd never do this in practice if all you wanted to do was to copy an existing list. You'd just do:

j = list(i)

Alternatively, if you wanted to use the Python list like an array in other languages, then you could pre-create a list with its elements set to a null value (None in the example below), and later, overwrite the values in specific positions:

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

The thing to realise is that a list object will not allow you to assign a value to an index that doesn't exist.

Steve Mayne
  • 22,285
  • 4
  • 49
  • 49
  • 2
    OK, thank you very much. I didn't know which one to praise as there are three almost same answers. This is most descriptive I think. Cheers – Vladan Apr 13 '11 at 18:11
  • 2
    I can see that this can be very confusing for those coming from other languages like PHP or C. j is a type of list, not an array. With list type, I don't think this is subscriptable. Very confusing if coming from other languages. – Nguai al Jan 12 '19 at 23:24
  • @Nguaial The list type is subscriptable, but you can only access elements that already exist - you can't create an element by attempting to write to an index that is out of range. j[0] = "foo" will work if the list already has at least one element. – Steve Mayne Jan 28 '19 at 13:49
  • I wonder about reasons behind this design decision... – x-yuri Dec 06 '20 at 20:15
  • after using the append it show the error cannot assign to function call – usman imtiaz Jul 20 '21 at 11:25
  • @usmanimtiaz you need to initialise the variables i j and k using the code in the original question. i = [1, 2, 3, 5, 8, 13] j = [] k = 0 – Steve Mayne Jul 21 '21 at 16:38
64

Your other option is to initialize j:

j = [None] * len(i)
Rsh
  • 7,214
  • 5
  • 36
  • 45
29

Do j.append(l) instead of j[k] = l and avoid k at all.

khachik
  • 28,112
  • 9
  • 59
  • 94
  • 3
    A shorter (more Pythonic?) way might be `j+=[l]` – Oleh Prypin Apr 13 '11 at 18:05
  • 2
    @BlaXpirit: It will put burden to the garbage collector, I think. – khachik Apr 13 '11 at 18:06
  • 4
    @BalXpirit: Given that is only saves a few characters (especially since you need to add spaces for it to be acceptable) and that `.append` is by far more common (perhaps for a reason - I think it's slightly easier to comprehend), not really superior in any way. (Edit @khachik: No, `+=` modifies in-place) –  Apr 13 '11 at 18:08
18

You could also use a list comprehension:

j = [l for l in i]

or make a copy of it using the statement:

j = i[:]
Jason Sundram
  • 12,225
  • 19
  • 71
  • 86
11
j.append(l)

Also avoid using lower-case "L's" because it is easy for them to be confused with 1's

jcp
  • 841
  • 1
  • 9
  • 14
Tom
  • 1,986
  • 2
  • 18
  • 29
8

I think the Python method insert is what you're looking for:

Inserts element x at position i. list.insert(i,x)

array = [1,2,3,4,5]
# array.insert(index, element)
array.insert(1,20)

print(array)

# prints [1,20,2,3,4,5]
Vallie
  • 689
  • 9
  • 19
Mehmet Kagan Kayaalp
  • 555
  • 2
  • 10
  • 21
  • 1
    There is no point using `insert` when `append` was provided specifically for this purpose. – holdenweb Oct 26 '19 at 12:34
  • 1
    On a point of information, your code in fact prints `[1, 20, 2, 3, 4, 5]`. – holdenweb Oct 26 '19 at 12:35
  • You inserted at index 1, displacing indices 1 and onwards. The inserted value does not end up at index 2. Iist.insert() is only really needed when you don’t want to add the item at the end of the list; the question here does exactly that so list.append() is preferable. – Martijn Pieters Oct 26 '19 at 13:34
  • Actually why I answer this question like that I am also suprised :D Do not know what I thought :) This is exactly "list.append()" which is the accepted answer. I think it helps people or give an idea to solve their problems so it gets 5 hits. – Mehmet Kagan Kayaalp Oct 28 '19 at 08:33
7

You could use a dictionary (similar to an associative array) for 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)

will print :

{0: 1, 1: 2, 2: 3, 3: 5, 4: 8, 5: 13}
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
Cedric
  • 5,135
  • 11
  • 42
  • 61
  • For consecutive indicies starting at 0 a mapping is usually the *wrong* data structure, especially when mappings do not have slicing or reversing as they are not intended to convey any specific order. – Martijn Pieters Oct 26 '19 at 13:37
2

One more way:

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

In this case j will be a numpy array

Alex
  • 944
  • 4
  • 15
  • 28
1

Maybe you need extend()

i=[1,3,5,7]
j=[]
j.extend(i)
Fred Moo
  • 11
  • 1