Python确保对象出现在列表的末尾

时间:2012-07-05 23:53:41

标签: python list sorting

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

4 个答案:

答案 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功能的任何建议都会很棒,因为它看起来有点讨厌。