Python 如何基于原始列表创建新列表相同的值但不同的索引

Python 如何基于原始列表创建新列表相同的值但不同的索引,python,list,pyqt5,qlistwidget,Python,List,Pyqt5,Qlistwidget,我在Python中使用Pyqt5创建了一个GUI界面,它导入一个Excel文件并在listWidget中将其列显示为项目。用户可以在其中检查项目,并将每个已检查项目附加到新的\u列表中 问题是,如果我有以下示例: original_list = ["a","b","c","d","e","f"] 如果用户为新列表选择以下项目: C、 f,a 结果是: 预期结果: 在此图像中,

我在Python中使用Pyqt5创建了一个GUI界面,它导入一个Excel文件并在listWidget中将其列显示为项目。用户可以在其中检查项目,并将每个已检查项目附加到新的\u列表中

问题是,如果我有以下示例:

original_list = ["a","b","c","d","e","f"]
如果用户为新列表选择以下项目:

C、 f,a

结果是: 预期结果: 在此图像中,用户在索引0处的项目之前选择索引3处的项目:

但是新的_列表将索引0处的项追加到索引3处的项之前

代码:
看起来selectionChanged的实现可以是下面的一行。
只需迭代并收集选中的项

def selectionChanged(self):
    self.checked = [self.header_list.item(row) for row in range(self.header_list.count()) if self.header_list.item(row).checkState()]
itemChanged信号还发送项目已更改的内容,这可用于操作列表

显然,如果您不断地创建一个新列表,那么就没有简单的方法来跟踪以前选择或不选择的内容,因此您需要一个持久的列表,并最终根据它们的检查状态追加/删除项目

请注意,我已经对代码的结构做了一些更改,稍后将详细介绍这一点

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.checked = []

    # ...

    def selectionChanged(self, item):
        if item.checkState():
            if item not in self.checked:
                self.checked.append(item)
        elif item in self.checked:
            self.checked.remove(item)
        print([i.text() for i in self.checked])


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())
除了显然需要在uu init_uuu中创建一个列表之外,修改的原因是您使用的可能是对pyuic生成的文件的修改:这些文件永远不应该被修改,也不应该尝试模仿它们的行为,应该始终按原样使用,并且只作为导入的文件使用。 即使在这种情况下,您也将Ui_MainWindow创建为QMainWindow的子类,但实际上并没有使用它。这样做并没有实际的好处,只会让事情变得更加复杂。我的建议是使用pyuic重新创建ui文件,然后将其导入脚本中,删除当前代码中的setupUi,并从导入文件的QMainWindow和ui_MainWindow中对主窗口进行子类化;假设文件导出为ui_MainWindow.py,则代码将如下所示:

from PyQt5 import QtCore, QtGui, QtWidgets
from ui_MainWindow import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.checked = []
        self.header_list.itemChanged.connect(self.selectionChanged)
# ...
有关正确使用这些文件的更多信息,请参阅关于的官方指南


最后,我强烈建议您使用,否则如果窗口太小,您的所有小部件都将无法使用,或者如果窗口太大,大量空间将无法使用。

您的回答给出了与我的问题相同的结果,而不是预期的结果。只需迭代并收集选中的项目即可。但是基于首先选择的项目意味着如果用户在self中首先选择项目索引3。检查[]将是项目索引0是否要收集所选项目的索引?不是索引,而是我的意思是:列表=[汽车、自行车、单元格]汽车在我的代码中有索引0 bike 1 cell 3我想如果用户先检查自行车然后检查汽车…self.check=[自行车,汽车]到目前为止,显示的结果始终是用户首先检查的结果。self.check将从列表中获取其索引等于的值。感谢您的帮助和解释,但我尝试了您的功能,它仍然返回相同的结果,而不是预期的结果one@RanyFahed代码有效,因此,请确保您正确地应用了我所做的更改,并且没有不断地重新创建列表。您所说的**您没有不断地重新创建列表**@RanyFahed是什么意思?正如答案中已经解释的那样,每次调用selectionChanged时,您都会在代码中创建一个新的自检列表。这显然是错误的,因为它不允许您以正确的顺序跟踪以前检查的项目。如果查看我的代码,self.checked列表只在_init__;中创建一次。我不想跟踪以前检查的项目。我想要的是,一旦我在标题列表中有了将创建一次的项目,但每次都会对其进行自检。。。。。。。那么你是说不能每次都创建self.checked??
def selectionChanged(self):
    self.checked = [self.header_list.item(row) for row in range(self.header_list.count()) if self.header_list.item(row).checkState()]
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.checked = []

    # ...

    def selectionChanged(self, item):
        if item.checkState():
            if item not in self.checked:
                self.checked.append(item)
        elif item in self.checked:
            self.checked.remove(item)
        print([i.text() for i in self.checked])


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())
from PyQt5 import QtCore, QtGui, QtWidgets
from ui_MainWindow import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.checked = []
        self.header_list.itemChanged.connect(self.selectionChanged)
# ...