class Company(object):
def __init__(self, name):
self.name = name
self.employees = {}
def addEmployee(self, id, name):
self.employees[id] = name
def displayEmployees(self):
tmp = [ (k,v) for k,v in self.employees.items() ]
tmp.sort()
for k,v in tmp:
print(k, '\t', v)
a = Company('The Company')
a.addEmployee(111, 'Employee1')
a.addEmployee(222, 'Employee2')
a.addEmployee(333, 'Employee3')
a.displayEmployees()
是否有另一种方法可以通过键对字典进行排序,以便在不使用新变量的情况下保持以下输出?:
111 Employee1
222 Employee2
333 Employee3
答案 0 :(得分:4)
对于大量员工而言,接近最优的可能是:
class Company(object):
def __init__(self, name):
self.name = name
self.employee_ids = []
self.employees = {}
self.sorted = True
def addEmployee(self, id, name):
self.employee_ids.append(id)
self.employees[id] = name
self.sorted = False
def displayEmployees(self):
if not self.sorted:
self.employee_ids.sort()
self.sorted = True
for k in self.employee_ids:
print k, '\t', self.employees[k]
这需要O(N)
来插入N
个员工 - 同时保持每个插入排序的self.employee_ids
会进行此类操作O(N squared)
。作为交换,这种方法使displayEmployees
最坏情况 O(N log N)
- 但往往更好,因为" timsort",Python&#39的超自然优秀表现在现实世界中的排序算法(自然合并的一种变体)。例如,如果您只添加一名员工(可能需要在中间使用随机ID),请拨打displayEmployees
,这只是O(N)
- timsort magic。
TL; DR:使用bisect
按排序顺序维护列表是一个经典且显然很酷的想法,但是,不要这样做。我不记得曾经看到一个明显胜利的情况。通常,最好只将append
新内容添加到列表中,并根据需要进行排序;偶尔,标准库中的模块heapq
(插入为O(log N)
,而不是O(N)
中的bisect
)可能更适合特殊应用。
还有一点需要注意:self.sorted
标记只是一个微小的(?)优化,如果您可能反复拨打displayEmployees
且中间没有addEmployee
来电;你可以通过省略它来简化代码,如果这样的模式不会发生,也不会产生任何不良影响 - 无论如何都不会改变大O行为: - )
答案 1 :(得分:2)
仅对键进行排序,并使用sorted()
函数查找值:
def displayEmployees(self):
for key in sorted(self.employees):
print(key, self.employees[key], sep='\t')
或内联排序项目:
def displayEmployees(self):
for key, value in sorted(self.employees.items()):
print(key, value, sep='\t')
答案 2 :(得分:0)
常规决定不记得订单。如果保留您的dict命令对于您的其余代码非常重要,则可以使用Python OrderedDict
模块中的collections
。您可以在添加员工时执行此操作:
from collections import OrderedDict
# ...
def addEmployee(self, id, name):
self.employees[id] = name
self.employees = OrderedDict(sorted(self.employees.items()))
这将始终保持您的self.employees
字典顺序,并将您的显示代码缩减为:
def displayEmployees(self):
for k,v in self.employees.items():
print(k, '\t', v)
答案 3 :(得分:0)
前几天我用__str__
方法创建了一个dict类,它可以按照你想要的方式显示项目。看看你是否对此感兴趣:
class EmployeeDict(dict):
'''Just a dictionary, but with a better display of data.
'''
def __str__(self):
str_output = ""
maxlen = len(str(max(self.keys())))
for key in sorted(self.keys()):
str_output += "{} | {}\n".format(str(key).rjust(maxlen), self[key])
return str_output
class Company(object):
def __init__(self, name):
self.name = name
self.employees = EmployeeDict()
def addEmployee(self, id, name):
self.employees[id] = name
def displayEmployees(self):
print(str(self.employees))
a = Company('The Company')
a.addEmployee(111, 'Employee1')
a.addEmployee(222, 'Employee2')
a.addEmployee(333, 'Employee3')
a.displayEmployees()
输出:
111 | Employee1
222 | Employee2
333 | Employee3