2015-06-02 3 views
1

У меня есть вложенный список с именем basic и я хочу изменить одну из его записей. Я предположил, что следующее поведение:неожиданное поведение вложенных списков в python

expected = [ [9],[0] ] 
unexpected = [ [9],[9] ] 
basic = [ [0],[0] ] 
basic[0][0] = 9 
print(basic == expected) # this is true 

Однако небольшая модификация дает удивительный результат:

Если список определен второй путь, присваивание устанавливает весь столбец 9.

Это поведение по дизайну? Если да, то почему? Я не могу найти ничего в документах об этом.

+1

Я рекомендую читать http://nedbatchelder.com/text/names.html – jonrsharpe

+0

+1 @jonrsharpe Я искал для этой ссылки! –

ответ

7

В первом примере:

basic = [ [0],[0] ] 

вы создали список объектов, содержащий два объекта списка. Вы можете видеть, что это разные объекты через id() или идентичность:

assert id(basic[0]) != id(basic[1]) 

assert basic[0] is not basic[1] 

В вашем втором примере:

l = [0] 
modified = [ l, l ] 

вы разместили тот же объект списка в другой список в два раза. Оба указателя указывают на один и тот же объект:

assert id(basic[0]) == id(basic[1]) 

assert basic[0] is basic[1] 

Итак, да. Вот как переменные (и объекты, на которые они указывают) работают в Python.

Чтобы получить ожидаемое поведение, необходимо создать отдельные объекты списка:

modified = [ l.copy(), l.copy() ] 
Смежные вопросы