0

I generate a list and each element in the list is a list too. I do it using a function with a 'for' loop in it. When I update the single value of the list it's updated in each sub-list instead.

I've noticed that when I create a list manually like:

array = [['O', 'O', 'O'], ['O', 'O', 'O'], ['O', 'O', 'O']]

all works as expected. But when I use my function which produces exactly the same output it fails.

def array_generation(size):
    array = []
    row = ['O'] * size
    for i in range(size):
        array.append(row)
    return array

myArray = array_generation(3)
myArray[0][0] = "S"

Actual Result: [['S', 'O', 'O'], ['S', 'O', 'O'], ['S', 'O', 'O']]

Expected Result: [['S', 'O', 'O'], ['O', 'O', 'O'], ['O', 'O', 'O']]

jamesoh
  • 372
  • 1
  • 10
Kowix
  • 11
  • 2
  • 2
    This because lists are passed by reference. Each individual list in your super-list is actually the same list. You need to create copies of the lists instead and modify those. Simply put array.append(row.copy()) in your array_generation() function instead. – jamesoh Aug 13 '19 at 07:36

3 Answers3

2

When you are generating your array, you append several times the same reference. So when you change the value of a pointer, you change every value.

Try that instead:

def array_generation(size):
    return [['O'] * size for _ in range(size)]
BlueSheepToken
  • 5,751
  • 3
  • 17
  • 42
1

You are using a reference to the same list 3 times. You should make a copy of it instead using the copy() built-in method:

def array_generation(size):
    array = []
    row = ['O'] * size
    for i in range(size):
        array.append(row.copy())
    return array
Silveris
  • 1,048
  • 13
  • 31
0

It's because you are adding the same three lists, it carries the same reference, you could either use copy or create Row inside the loop like this:

def array_generation(size):
    DefArray = []
    for i in range(size):
        row = ['O'] * size
        DefArray.append(row)
    return DefArray
palvarez
  • 1,508
  • 2
  • 8
  • 18