首页 > 解决方案 > 存储 Employee 对象的最佳数据结构?

问题描述

我想创建一个 GUI,允许用户创建新的员工对象并访问它们各自的属性。到目前为止,我的程序只允许一次打印一个对象的信息:

import sys
from PyQt4 import QtGui

class Employee:

  def __init__(self, id, salary):
    self.id = id
    self.salary = salary

  def info(self):
    return "Employee ID: {}\nFull name:{}\nSalary:{}".format(self.id, self.full_name, self.salary)

class Window(QtGui.QMainWindow, Employee):

  def __init__(self):
    super(Window, self).__init__()  #Returns the parent object or the QMainWindow object
    self.setGeometry(50, 50, 500, 300)
    self.setWindowTitle("Employee builder")

    extractAction = QtGui.QAction("&Add Employee", self)
    extractAction.triggered.connect(self.create_employee)

    mainMenu = self.menuBar()
    fileMenu = mainMenu.addMenu('&File')
    fileMenu.addAction(extractAction)

    self.home()

  def home(self):
    self.show()

  def create_employee(self):
    ID, ok = QtGui.QInputDialog.getInt(self, "integer input dualog", "Enter employees id number:")
    pay, ok = QtGui.QInputDialog.getInt(self, "integer input dualog", "Enter employees salary:")

    emp1 = Employee(ID, pay)
    QtGui.QMessageBox.information(None, "Employee information:", emp1.info)

def run():
  app = QtGui.QApplication(sys.argv)
  GUI = Window()
  sys.exit(app.exec_())

run()

我看到的下一个逻辑步骤是调用一个存储每个新创建的员工对象的方法,以便用户可以根据对象 ID 访问对象信息。在 Python 中,创建更高级的数据结构(如哈希表)来存储对象是否值得?还是我应该只使用字典或列表(字典是哈希表)?我这样做只是为了学习 Python 和 PyQt4 GUI,所以我不希望节省兆字节的员工信息或类似的东西。

标签: pythonpython-3.x

解决方案


如果您需要有效地(摊销的常数时间)和方便地按键查找,哈希表是一种很好的数据结构。

Pythondict使用哈希表,因此它完全可以满足您的要求。(当然,如果您想构建自己的哈希表作为一种学习体验,这并不难。但是您不太可能获得与内置哈希表一样好的性能,尤其是如果您使用的是默认的 CPython 解释器。 )


使用 adict使您的代码更易于编写和阅读。如果你制作employees一个对象,要通过 ID 找到一个listEmployee你必须这样做:

for employee in employees:
    if employee.id == searchid:
        do_stuff(employee)
        break

但是,如果你让 if a dict,每个每个employee值都由它的键控employee.id,你可以这样做:

employee = employees[searchid]

(当然在现实生活中的代码中,两个版本都需要更多的时间来处理找不到 ID 的情况。)

而且它也更有效率。循环显然是在访问每个员工(好吧,多亏了break,我们平均只访问了其中的一半,但在最坏的情况下仍然是全部),但该dict版本只是散列searchid并在散列表中查找它。因此,如果您将表设置为 10000 倍那么大,则该list版本需要 10000 倍的时间,但该dict版本仍然有效地是即时的。


但是,如果你想做一些事情,比如用 查找所有员工id<=20,哈希表将无济于事。相反,您需要一个可以在对数时间内平分的排序集合。

对于静态数据,您在开始时进行所有插入,然后只进行查询,您可以只使用列表sort(key=operator.attrgetter('id')),然后使用bisect模块进行搜索。

如果您需要在系统的整个生命周期中频繁地添加(或删除)条目,您需要一种树状数据结构——红黑树或其他平衡二叉搜索树,或者 b-tree 变体之一,或者跳过列表等。Python 没有附带任何这些,但是 PyPI 上都有很好的实现(或者可能值得自己构建一个作为练习)。

还有一些巧妙的混合结构,它们在小尺度上基本上就像一个绳索/双端队列,但在大尺度上就像一个 b-tree 或一个宽的跳过列表,这可能会更好。这些也可以在 PyPI 上找到。


推荐阅读