Список списков Python - доступ к отдельным элементам - PullRequest
0 голосов
/ 04 марта 2012

Я пытаюсь получить доступ к определенному элементу списка списков в Python.Я привожу немного багажа C / Java и рассматриваю эту структуру данных как двумерный массив.На мой взгляд, операция ниже должна повлиять только на первый элемент первого списка, loc1[0][0] на Java.На практике затрагивается первый элемент каждого подсписка, то есть loc1[0][0], loc1[1][0] и loc1[2][0].Есть идеи, почему это так?

def move(loc, dir, nrows, ncols):
  loc1 = [[0.0] * ncols] * nrows

  for col in range(1):
      for row in range(1):
          loc1[row][col] += 100.0 * loc[row][col]

  return loc1
nrows = 4
ncols = 3
p = [[1.0 / (ncols * nrows)] * ncols] * nrows #uniform prior

print p
p = move(p, [0, 1], nrows, ncols)
print p

Ответы [ 2 ]

4 голосов
/ 04 марта 2012

У меня было такое раньше, и это расстраивает.

Ваша проблема в этой строке кода, которая не выполняет то, о чем вы думаете:

loc1 = [[0.0] * ncols] * nrows

[0.0] * ncols создает один список, который передается по ссылке для формирования вашего 2D-списка.

Попробуйте это:

loc1 = [[0.0 for y in range(ncols)] for x in range(nrows)]
3 голосов
/ 04 марта 2012

[x]*n создает список, который содержит один и тот же элемент x n раз.

L = [0.0] * ncols работает, потому что 0.0 - это число с плавающей точкой, а значения с плавающей точкой неизменны в Python, поэтому L[0] += 1.1не меняет 0.0, но ставит 1.1 на свое место.

Списки изменчивы, поэтому, когда вы изменяете любую строку в L = [[0]*ncol]*nrow, вы изменяете их все, потому что это один и тот же объект.

Чтобы исправить это, вы можете:

L = [[0.0]*ncols for _ in xrange(nrows)]

Он создает новый список для каждой строки, так что вы можете изменить их независимо.

Или:

from itertools import repeat

L = [[0.0]*ncols for _ in repeat(None, nrows)]

Все, что более читабельно для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...