title: pyqt QAbstractTableModel implementation of setData changes values of wrong items
body: <p>I have subclassed QAbstractTableModel (using PyQt4), including the setData method. My data is held in a nested list, with column headers ("col_headers") and row headers ("row_headers) stored in lists. Row and col headers are not unique in case that is relevant.</p>
  
  <p>Here's the init:</p>
  
  <pre><code>def __init__(self):
      self.arraydata = [[]]
      self.col_headers = [] # Columns
      self.row_headers = [] # Rows
  </code></pre>
  
  <p>I have implemented setData as follows (with some debugging print statements):</p>
  
  <pre><code>def setData(self, index, value, role=QtCore.Qt.EditRole):
      row = index.row()
      column = index.column()
      print('row {} col {}'.format(row, col) # This gives the expected values
      print('data before: {}'.format(self.arraydata) # The before state
      self.arraydata[row][column] = value
      print('data after: {}'.format(self.arraydata) # The after state = the problem
      self.dataChanged.emit(index, index)
  </code></pre>
  
  <p>This usually works when I first start running it, and the table populates as expected, one cell at a time.</p>
  
  <p>However, as more setData calls come through, instead of only updating the particular item, it often (but not always) updates the value for the same column for most or all of the other rows. This problem is made worse (or triggered if it hasn't already happened) if my view of the model (a QTableView) is scrolled or resized, or the window is resized.</p>
  
  <p>So my question is, how do I setData on my model so that only one item in the model is changed? And is a list of lists the correct way for me to be holding the data? Finally, could the problem be caused by too many emits in quick succession to the view, with the subsequent callbacks "under the hood" by the view to the model messing with the indexing?</p>
  
  <p>Full (simplified) code:</p>
  
  <pre><code>from PyQt4 import QtCore, QtGui
  
  ROWS = 0
  COLS = 0
  
  class MyTableModel(QtCore.QAbstractTableModel):
  
      def updateData(self, row_header, col_header, value):
          ix_to_chg = []
          for i, row_h in enumerate(self.row_headers):
              for j, col_h in enumerate(self.col_headers):
                  if row_h == row_header and col_h == col_header:
                      ix_to_chg.append((i, j))
          for i, j in ix_to_chg:
              index=self.index(i, j)
              self.setData(index=index, value=value, role=QtCore.Qt.EditRole)
  
      def insertRows(self, position, count, new_row_headers, parent=QtCore.QModelIndex()):
          self.beginInsertRows(QtCore.QModelIndex(), position, position + count -1)
          empty_row = ['' for x in range(self.columnCount())]
          for i in range(count):
              self.arraydata.insert(position, empty_row)
              new_row_header = new_row_headers[::-1][i]
              self.row_headers.insert(position, new_row_header)
          self.endInsertRows()
  
      def insertColumns(self, position, count, new_col_headers, parent=QtCore.QModelIndex()):
          self.beginInsertColumns(QtCore.QModelIndex(), position, position + count -1)
          empty_cell = ''
          for i in range(count):
              self.arraydata[0].insert(position+i, empty_cell)
              new_col_header = new_col_headers[i]
              self.col_headers.insert(position + i, new_col_header)
          self.endInsertColumns()
  
      def setData(self, index, value, role=QtCore.Qt.EditRole):
          row = index.row()
          column = index.column()
          print('row {} col {}'.format(row, column)) # This gives the expected values
          print('data before: {}'.format(self.arraydata)) # The before state
          self.arraydata[row][column] = value
          print('data after: {}'.format(self.arraydata)) # The after state = the problem
          self.dataChanged.emit(index, index)
  
      def data(self, index, role=QtCore.Qt.DisplayRole):
          if role == QtCore.Qt.DisplayRole:
              i = index.row()
              j = index.column()
              return '{}'.format(self.arraydata[i][j])
          else:
              return None
  
      def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
          if role == QtCore.Qt.DisplayRole:
              if orientation == QtCore.Qt.Horizontal:
                  if self.columnCount() == 0:
                      return []
                  else:
                      return self.col_headers[section]
              else:
                  if self.rowCount() == 0:
                      return []
                  else:
                      return self.row_headers[section]
  
      def flags(self, index):
          return QtCore.Qt.ItemIsEnabled
  
      def rowCount(self, parent=QtCore.QModelIndex()):
          return len(self.arraydata)-1
  
      def columnCount(self, parent=QtCore.QModelIndex()):
          return len(self.arraydata[0])
  
      def setupModel(self, numRows, numCols):
          for row_num in range(numRows):
              for col_num in range(numCols):
                  if self.rowCount(self) &lt; numRows:
                      for i in range(numRows - self.rowCount(self)):
                          self.arraydata.append([])
                  if self.columnCount(self) &lt; numCols:
                      for i in range(numCols - self.columnCount(self)):
                          for j in range(self.rowCount(self)):
                              item = '_'.join(['row', str(j), 'col', str(i)])
                              self.arraydata[j].append(item)
  
      def __init__(self, col_headers=None, row_headers=None, rows=ROWS, cols=COLS):
          QtCore.QAbstractTableModel.__init__(self)
          self.arraydata = [[]]
          col_headers = ['emptyColHeader' for i in range(cols)] if col_headers is None else col_headers
          row_headers = ['emptyRowHeader' for i in range(rows)] if row_headers is None else row_headers
          self.col_headers = col_headers
          self.row_headers = row_headers
  </code></pre>
  
  <p>EDIT:</p>
  
  <p>Solved it (with thanks to <a href="https://stackoverflow.com/questions/240178/python-list-of-lists-changes-reflected-across-sublists-unexpectedly">List of lists changes reflected across sublists unexpectedly</a>).</p>
  
  <p>In <code>insertRows()</code> I was adding the same list in a loop to each row - they were all referring to <em>the same</em> list. The new code for that function:</p>
  
  <pre><code>def insertRows(self, position, count, new_row_headers, parent=QtCore.QModelIndex()):
      self.beginInsertRows(QtCore.QModelIndex(), position, position + count -1)
      empty_row = ['' for x in range(self.columnCount())]
      for i in range(count):
          self.arraydata.insert(position, empty_row.copy())
          new_row_header = new_row_headers[::-1][i]
          self.row_headers.insert(position, new_row_header)
      self.endInsertRows()
  </code></pre>