我有一个Job类。这是一个包含一些示例作业的简化版本:
class Job:
def __init__(self, type):
self.type = type
def __repr__(self):
return '< %s >' % self.type
job1 = Job('Copy')
job2 = Job('Delete')
job3 = Job('Scan')
jobs = [job1,job2,job3]
在我的应用程序中,作业会随机添加到jobs
列表(来自数据库),但我需要确保最后发生任何Delete
个作业。我能想到的最简单的方法是确保将Delete
作业移动到列表的末尾,然后按顺序处理列表。但是,当排序条件是类的属性时,我不确定如何做到这一点,并且是否有任何保证在处理作业时按顺序迭代列表?任何建议都会很棒。
答案 0 :(得分:6)
jobs.sort(key=lambda x:x.type=="Delete")
对于“复制”或“扫描”作业,密钥为False
,对于“删除”作业,密钥为True
。自True
&gt; False
“删除”作业将排序到最后
答案 1 :(得分:2)
保证排序稳定,因此只需实施__cmp__
:
class Job:
def __init__(self, type):
self.type = type
def __repr__(self):
return '< %s >' % self.type
def __cmp__(self, other):
if self.type == 'Delete':
return 0 if other.type == 'Delete' else 1
return -1 if other.type == 'Delete' else 0
在处理之前对列表进行排序:
jobs.sort()
答案 2 :(得分:1)
这是一个将'Delete'
作业以线性时间转换到结尾的函数。但它不会保留秩序。使用sort
在半排序数据和简短列表上可能会更快,但我想我会发布一个替代方案,因为gnibbler打败了我的排序选项(并且更好地启动)。 / p>
def shift_delete_jobs(jobs):
end = len(jobs) - 1
for i in reversed(range(len(jobs))):
if jobs[i].type == 'Delete':
jobs[end], jobs[i] = jobs[i], jobs[end]
end -= 1
答案 3 :(得分:0)
我会做一个工作容器类:
class JobContainer(object):
def __init__(self, jobs):
self.jobs = jobs
def get_type(self, type, invert=False):
return [job for job in jobs if (job.type == type) ^ invert]
def get_jobs(self):
return self.get_type('Delete', invert=True) + self.get_type('Delete')
然后像这样使用它:
jobs = JobContainer([job1, job2, job3])
print jobs.get_jobs()
关于如何改进get_jobs
功能的任何建议都会很棒,因为它看起来有点讨厌。