1

我有一个工作课程。这是带有一些示例作业的简化版本:

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作业移动到列表的末尾,然后按顺序处理列表。但是,当排序标准是类的属性时,我不确定如何做到这一点,并且是否可以保证在处理作业时列表将按顺序迭代?任何建议都会很棒。

4

4 回答 4

6
jobs.sort(key=lambda x:x.type=="Delete")

键将False用于“复制”或“扫描”作业以及True“删除”作业。由于True> False“删除”作业将被排序到最后

于 2012-07-05T23:56:01.330 回答
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()
于 2012-07-05T23:58:08.477 回答
1

这是一个'Delete'在线性时间内将工作转移到最后的函数。但它不会保持秩序。sort在半排序数据和短列表上使用可能会更快,但我想我会发布一个替代方案,因为gnibbler击败了我到排序选项(并且在启动时做得更好)。

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
于 2012-07-05T23:56:47.487 回答
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功能的建议都会很棒,因为它看起来有点讨厌。

于 2012-07-05T23:57:10.807 回答