Как индексировать словарь в цикле for python

У меня есть структура данных, которая по существу представляет собой вложенный словарь. Скажем, это выглядит так:

standard_dict = {
        'section1': {
            'category1': np.array([1, 2, 3, 5]),
            'category2': 2
        },
        'section2': {
             'category1': [4, 5, 6],
             'category2': {'category2a': {'t': 1}}
        }
    }

Кроме того, у меня есть рекурсивная функция с циклом for для создания вложенного дерева из этого словаря. Теперь я пытаюсь добавить в цикл for индекс для каждого значения пары ключей. Я пробовал это с QModelindex, но я не дошел до того, что код делает то, что я хочу.

    def add_object(self, v: object, prefix1: object) -> object:
        if isinstance(v, dict):
            for k, v2 in v.items():
                prefix1.addChild(CustomNode(k))
                prefix = prefix1.getlastChild()
                self.add_object(v2, prefix)
                
        elif isinstance(v, list):
            for e in v:
                prefix1.addChild(CustomNode(e))

Есть ли простой способ реализовать и добавить индекс к значению пары ключей?

Результат, который я хотел бы получить, - это обновить только измененные отдельные значения в графическом интерфейсе PyQt5, а не весь графический интерфейс.

Вот весь мой проект, если кто-то хочет знать.

"""
import copy
from typing import List, Any
import sys
from PyQt5 import QtCore, QtWidgets, uic
import numpy as np
from deepdiff import DeepDiff
from lib.MainWindow import Ui_MainWindow


class CustomNode(object):
    def __init__(self, data):
        self._data = data
        if type(data) == tuple:
            self._data = list(data)
        if type(data) is str or not hasattr(data, '__getitem__'):
            self._data = [data]

        self._columncount = len(self._data)
        self._children = []
        self._parent = None
        self._row = 0

    def getlastChild(self):
        return self._children[-1]

    def data(self, column):
        if column >= 0 and column < len(self._data):
            return self._data[column]

    def columnCount(self):
        return self._columncount

    def childCount(self):
        return len(self._children)

    def child(self, row):
        if row >= 0 and row < self.childCount():
            return self._children[row]

    def parent(self):
        return self._parent

    def row(self):
        return self._row

    def addChild(self, child):
        child._parent = self
        child._row = len(self._children)
        self._children.append(child)
        self._columncount = max(child.columnCount(), self._columncount)


class CustomModel(QtCore.QAbstractItemModel):
    def __init__(self, nodes):
        QtCore.QAbstractItemModel.__init__(self)
        self._root = CustomNode(None)
        for node in nodes:
            self._root.addChild(node)

    def rowCount(self, index: object) -> object:
        if index.isValid():
            return index.internalPointer().childCount()
        return self._root.childCount()

    def addChild(self, node, _parent):
        if not _parent or not _parent.isValid():
            parent = self._root
        else:
            parent = _parent.internalPointer()
        parent.addChild(node)

    def index(self, row, column, _parent=None):
        if not _parent or not _parent.isValid():
            parent = self._root
        else:
            parent = _parent.internalPointer()

        if not QtCore.QAbstractItemModel.hasIndex(self, row, column, _parent):
            return QtCore.QModelIndex()

        child = parent.child(row)
        if child:
            return QtCore.QAbstractItemModel.createIndex(self, row, column, child)
        else:
            return QtCore.QModelIndex()

    def parent(self, index):
        if index.isValid():
            p = index.internalPointer().parent()
            if p:
                return QtCore.QAbstractItemModel.createIndex(self, p.row(), 0, p)
        return QtCore.QModelIndex()

    def columnCount(self, index):
        if index.isValid():
            return index.internalPointer().columnCount()
        return self._root.columnCount()

    def data(self, index, role):
        if not index.isValid():
            return None
        node = index.internalPointer()
        if role == QtCore.Qt.DisplayRole:
            return node.data(index.column())
        return None


class MyTree():

    def __init__(self, ref_dict, treeView):
        self.items = []
        self.ref_dict = ref_dict
        self.items = []
        self.index_dict = ref_dict


        '''Erzeugt eine List aus den Hauptitems'''
        for key in self.ref_dict:
            self.items += [CustomNode(key)]
            self.add_object(self.ref_dict[key], prefix1=self.items[-1])

        '''Aufruf der View um die Anzeige darzustellen'''
        # self.tw = QtWidgets.QTreeView()
        self.tw = treeView
        self.tw.setModel(CustomModel(self.items)) #referenz auf das Modell, gibt das Modell zurück
        print(self.tw.model())

    '''Funktion um das Dictionary zu iterieren und in einer Treeview darzustellen'''
    def add_object(self, v: object, prefix1: object) -> object:
        if isinstance(v, dict):
            for k, v2 in v.items():
                prefix1.addChild(CustomNode(k))
                prefix = prefix1.getlastChild()
                self.add_object(v2, prefix)
                
        elif isinstance(v, list):
            for e in v:
                prefix1.addChild(CustomNode(e))

        elif isinstance(v, type(np.array([]))):
            [prefix1.addChild(CustomNode(int(i))) for i in v]

        else:
            prefix1.addChild(CustomNode(v))

    

class Compare():
    def __init__(self, standard_dict):
        self.__standard_dict = copy.deepcopy(standard_dict)

    @property
    def standard_dict(self):
        return self.__standard_dict

    @standard_dict.setter
    def standard_dict(self, standard_dict):
        self.__standard_dict = standard_dict
        # Signal auslösen mit kompletten Update vom Model

    '''Funktion um mit DeepDiff die beiden Dictionaries zu vergleichen'''
    def compare(self, new_dict):
        return DeepDiff(self.__standard_dict, new_dict)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        mytree = MyTree(standard_dict, self.ui.treeView)
        mytree_2 = MyTree(standard_dict, self.ui.treeView_2)
        self.ui.pushButton.clicked.connect(self.compare_dict)
        self.comp = Compare(standard_dict=standard_dict)

    def compare_dict(self):
        standard_dict['section1']['category2'] += 1
        diff = self.comp.compare(standard_dict)
        self.ui.plainTextEdit.insertPlainText(str(standard_dict))
        self.ui.plainTextEdit.insertPlainText(str(diff))
        #mytree_3 = MyTree(standard_dict, self.ui.treeView_2)
        #nur die Stelle des geänderten Indexes updaten und keine neue View erstellen


if __name__ == "__main__":

    standard_dict = {
        'section1': {
            'category1': np.array([1, 2, 3, 5]),
            'category2': 2
        },
        'section2': {
             'category1': [4, 5, 6],
             'category2': {'category2a': {'t': 1}}
        }
    }

    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

Заранее большое спасибо


person aeschcol    schedule 24.06.2020    source источник
comment
Спасибо за совет. Я прочитал этот пост, но когда я добавляю индекс в свой цикл for, индекс показывает только значения 0 и 1. def add_object(self, v: object, prefix1: object) -> object: if isinstance(v, dict): для i, (k, v2) в enumerate(v.items()): prefix1.addChild(CustomNode(k)) prefix1.addChild(CustomNode(i)) prefix = prefix1.getlastChild() print(index: {}, ключ: {}, значение: {}.format(i, k, v2)) self.add_object(v2, префикс)   -  person aeschcol    schedule 25.06.2020