Добавление 2d списка Python не работает, как и ожидалось, это ошибка? - PullRequest
1 голос
/ 12 апреля 2019

Я столкнулся с проблемой при добавлении списка в список 2D.В коде ниже, если я изменю b.append(a) на b.append([*a]), все работает!Но разве a и [*a] не одинаковы?

a = ['1', '1', '1']
b = []

def call_other(ar):
    a[0], a[1], a[2] = ar[0], ar[1], ar[2]
    print('a is', a)
    b.append(a)
    print('b is', b)
    print()

def lop():
    for i in range(5):
        c = ['0', '1', '1']
        if i >  1:
            c = ['1', '0', '1']
        call_other(c)

lop()           
print('final b:', b)

Вывод:

a is ['0', '1', '1']
b is [['0', '1', '1']]

a is ['0', '1', '1']
b is [['0', '1', '1'], ['0', '1', '1']]

a is ['1', '0', '1']
b is [['1', '0', '1'], ['1', '0', '1'], ['1', '0', '1']]

a is ['1', '0', '1']
b is [['1', '0', '1'], ['1', '0', '1'], ['1', '0', '1'], ['1', '0', '1']]

a is ['1', '0', '1']
b is [['1', '0', '1'], ['1', '0', '1'], ['1', '0', '1'], ['1', '0', '1'], ['1', '0', '1']]

final b: [['1', '0', '1'], ['1', '0', '1'], ['1', '0', '1'], ['1', '0', '1'], ['1', '0', '1']]

1 Ответ

1 голос
/ 12 апреля 2019

Существует принципиальная разница между следующими двумя частями кода:

a = [1, 1, 1]
b.append(a)
a[0] = 0
b.append(a)

и

a = [1, 1, 1]
b.append([*a])
a[0] = 0
b.append([*a])

В первом случае вы добавляете одну и ту же ссылку к b каждый раз. Когда вы изменяете элемент исходного списка a с помощью a[0] = 0, это изменение будет видно для всех ссылок на этот список. Следовательно, b будет [[0, 1, 1], [0, 1, 1]], а не [[1, 1, 1], [0, 1, 1]].

Во втором случае [*a] создает новый список, содержащий копию всех элементов a. Когда вы обновляете исходный список, ссылка, которая уже есть в b, не указывает на тот же список и поэтому остается неизменной. Вот почему b будет [[1, 1, 1], [0, 1, 1]].

...