好的伙计,这是一个奇怪的。
Theres'是一个允许附加文件的GUI(在wxPython中)。文件路径保存到类属性self.pathList
。这些路径显示在GUI上,并使用两个功能进行编辑(绑定到按钮); OnAttach()
和OnView()
。第一个,顾名思义,允许用户选择文件,而第二个允许用户查看这些文件的列表并选择要删除的文件。
有两个问题:
[已解决]这些项目已添加到self.pathList
,无需考虑排序。无论是否应用sorted()
,列表永远不会排序。我们通过选择100个名为“1.txt”,“2.txt”的文本文件来测试它,依此类推。订单似乎是随机的。这两个函数的完整代码如下,但有问题的行是:
self.pathList = list(set(self.pathList + [str(path) for path in sorted(dlg.GetPaths())]))
同样,应用sorted
的地方(或者根本不存在)并不重要,结果是一样的。以下两行都返回相同的self.pathList
:
self.pathList = list(set(self.pathList + [str(path) for path in dlg.GetPaths()]))
self.pathList = sorted(list(set(self.pathList + [str(path) for path in dlg.GetPaths()])))
IndexError: pop index out of range
希望有人能理解这一点。提前致谢
def OnAttach(self, event, viewattBtn):
"""Select a File"""
self.dirname = ''
dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.*", wx.OPEN|wx.MULTIPLE|wx.FD_FILE_MUST_EXIST)
if dlg.ShowModal() == wx.ID_OK:
self.pathList = list(set(self.pathList + [str(path) for path in sorted(dlg.GetPaths())]))
for path in self.pathList:
self.fileNameList.append(path.split('\\')[-1])
self.fileNameList = list(set(self.fileNameList)) #Applying sorted() here fixes the first issue
self.att.SetLabel('\n'.join(self.fileNameList))
self.vbox.Layout()
self.panel.FitInside()
if self.pathList != []: viewattBtn.Enable(True)
return viewattBtn
dlg.Destroy()
def OnView(self, event, viewattBtn):
dlg = wx.MultiChoiceDialog(self, "Attachments (Select attachments and push 'OK' to delete)", "", self.fileNameList, wx.OK|wx.CANCEL)
if options.diagMode: print self.fileNameList
if dlg.ShowModal() == wx.ID_OK:
selections = reversed(sorted(dlg.GetSelections()))
selections = [self.fileNameList[index] for index in selections]
for item in selections:
pathIndex = selections.index(item)
self.pathList.pop(pathIndex)
self.fileNameList.remove(item)
self.att.SetLabel('\n'.join(self.fileNameList))
self.vbox.Layout()
self.panel.FitInside()
if self.fileNameList == []: viewattBtn.Enable(False)
return viewattBtn
dlg.Destroy
编辑:第一个问题是在标记的行上按已排序的fileNameList
修复的
答案 0 :(得分:1)
对于您的第一个问题,问题是您要从排序列表中创建set
。集没有定义的顺序;事实上,订单记录是任意的。
解决方案是首先不要创建set
。
如果您需要消除重复项,可以使用unique_everseen
文档中的itertools
之类的配方,或者使用某种OrderedSet
类。如果您不需要消除重复,只需按原样使用列表:
self.pathList = self.pathList + [str(path) for path in sorted(dlg.GetPaths())]
(另外,如果 想要一个集合,您可能不希望将该集合转换为列表并将其添加到另一个列表中;您只想将其保存为另一个列表;设置在第一位。)
对于你的第二个问题,我不确定你的代码是做什么的,但它几乎肯定是完全错误的。
首先,您从不想要遍历列表,然后搜索值的索引。如果有任何重复,这是错误的,而且非常慢,而且非常复杂。只需保持索引:
for index, item in enumerate(selections):
其次,我不认为selections
中的索引与pathList
和fileNameList
中的索引有任何关系,在这种情况下使用索引不能正常工作第一名。
但即使索引在开始时相同,每次pop
列表中的某些内容时,所有剩余的元素都会向上移动一个,因此索引为no在第一个pop
之后更长。
我认为重新组织你的数据结构会更好 - 而不是保留一堆列表,保留一个列表,无论什么东西需要有一个已定义的顺序,并保留其他所有内容作为dicts,使用来自首先列为键。
答案 1 :(得分:1)
使用set
会重新排序您的商品,并将其分类。不要那样做,或者在之后对进行排序,然后将集合转换回列表。
当您从pathList
中移除项目时,该列表中项目的位置将发生变化,并且将不再与您从selections
获得的数字相对应。删除足够多的项目后,其中一个索引将超出列表的大小。