2015-07-24 3 views
-1

Я пытаюсь представить матрицу в виде списка списков и заполнить ее значениями, основанными на погоде, положение в матрице удовлетворяет некоторым условиям. Переменная, которую я храню, составляет self._solution.Нежелательное поведение по Python Список списков

Для того, чтобы продолжить, я беру 2 различных подхода: Подход 1:

def __init__(self, N=3, puzzle=None): 
     self.N = N 
     self.SIZE = self.N*self.N 
     self.puzzle = [[set([1])]*(self.SIZE)]*(self.SIZE) 
     if puzzle is None: 
      for i in range(self.SIZE): 
       self.puzzle[i] = [int(k) for k in raw_input()] 
     else: 
      self.puzzle = [[int(k) for k in line] for line in puzzle.splitlines()] 

     self._empty_cells = 0  
     self._solutions = [[0]*(self.SIZE)]*(self.SIZE) 
     self._solutions = [] 
     print self.puzzle 
     print self._solutions 
     for i in range(self.SIZE): 
      self._solutions.append([]) 
      for j in range(self.SIZE): 
       if self.puzzle[i][j] < 1: 
        #self._solutions[i][j] = set(range(1,self.SIZE+1)) 
        self._solutions[i].append(1) 
        self._empty_cells += 1 
        print "puzzle[%s][%s] = %s\tsolutions[%s][%s] = %s" % (i,j, self.puzzle[i][j], i, j, self._solutions[i][j]) 
       else: 
        self._solutions[i].append(0) 
     print self._solutions 

подход 2:

def __init__(self, N=3, puzzle=None): 
     self.N = N 
     self.SIZE = self.N*self.N 
     self.puzzle = [[set([1])]*(self.SIZE)]*(self.SIZE) 
     if puzzle is None: 
      for i in range(self.SIZE): 
       self.puzzle[i] = [int(k) for k in raw_input()] 
     else: 
      self.puzzle = [[int(k) for k in line] for line in puzzle.splitlines()] 

     self._empty_cells = 0  
     self._solutions = [[0]*(self.SIZE)]*(self.SIZE) 
     #self._solutions = [] 
     print self.puzzle 
     print self._solutions 
     for i in range(self.SIZE): 
      #self._solutions.append([]) 
      for j in range(self.SIZE): 
       if self.puzzle[i][j] < 1: 
        #self._solutions[i][j] = set(range(1,self.SIZE+1)) 
        self._solutions[i][j] = 1 
        #self._solutions[i].append(1) 
        self._empty_cells += 1 
        print "puzzle[%s][%s] = %s\tsolutions[%s][%s] = %s" % (i,j, self.puzzle[i][j], i, j, self._solutions[i][j]) 
     print self._solutions 

Что я считаюсь как значение self._solution установлен. В идеале оба подхода должны работать лучше всего, однако выход двух подходов значительно отличается. Я бы хотел, чтобы позиции, удовлетворяющие условию self.puzzle[i][j] == 0, были установлены в 1. Однако в подходе 2 все значения self._solution установлены в 1, тогда как подход 1 работает правильно.

Также в подходе 2, если я просто добавляю блок else после состояния if self.puzzle[i][j] == 0, а затем устанавливаю значение self._solution[i][j] = 0, тогда выход будет правильным.

Может ли кто-нибудь объяснить это странное поведение. Кто-нибудь еще видел похожие результаты.

Я использую IPython и Python 2.7

Edit: Это не дубликат unexpected behaviour of nested lists in python как это один касается оператора * как указал @Crazy Каста. Также я понял, что случай, когда у меня есть что-то вроде этого: self._solutions = [[set([])]*SIZE]*SIZE еще более опасен, поскольку каждый созданный элемент набора указывает на тот же элемент в памяти.

+0

Возможный дубликат [неожиданного поведения вложенных списков в python] (http://stackoverflow.com/questions/30703303/unexpected-behaviour-of-nested-lists-in-python) – NightShadeQueen

+1

@NightShadeQueen Я должен не согласиться. Ничто в этом вопросе не связано с оператором * в списках, вот в чем проблема. – CrazyCasta

ответ

1

Много, чтобы принять, но я предполагаю, что у вас возникли проблемы с этим битом:

self._solutions = [[0]*(self.SIZE)]*(self.SIZE) 

Если предположить, что вы пытаетесь сделать, это self.SIZE независимые списки размера self.SIZE то вам «Не получишь того, что хочешь. Синтаксис умножения списка, который вы используете, копирует ссылку, поэтому у вас есть список self.SIZE ссылок на один и тот же список. Чего вы хотите:

self._solutions = [[0]*(self.SIZE) for _ in range(self.SIZE)] 

Это создаст новый список self.SIZE раз вместо того, чтобы повторно использовать один и тот же.

+0

Решил мою проблему. –

Смежные вопросы