首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python:根据两个属性对列表进行排序

Python:根据两个属性对列表进行排序
EN

Stack Overflow用户
提问于 2013-08-26 15:15:35
回答 4查看 398关注 0票数 4

我有一份清单如下:

代码语言:javascript
复制
class Ind(object):
    def __init__(self,ID,mate):
        self.ID=ID
        self.mate=mate

population=[Ind(8,None), Ind(1,2), Ind(20,3), Ind(2,1), Ind(12,None), Ind(3,20), Ind(10,11), Ind(11,10)]

你可以把这个列表population看作是一个个体群体,所有的个体都有一个ID。他们中的一些人有一个mate (一个在同一人群或同一名单中的个体)。mate值实际上是配偶的ID!因此,如果有一个属性为IndID = 12而mate为34的实例,那么列表中必然有一个ID = 34而mate为12的个体。没有mate的个体在mate属性中有None。说得通吗?

我想对这个列表进行排序,以便第一个个体和最后一个个体,第二个个体和第二个到最后一个个体,等等.属性为mate等于None的个人应该站在列表的中间。

有许多可能的输出符合我的要求。以下是上述列表中这些输出的一个示例:

代码语言:javascript
复制
population=[Ind(1,2), Ind(20,3), Ind(10,11), Ind(8,None), Ind(12,None), Ind(11,10), Ind(3,20), Ind(2,1)]
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-08-26 15:29:21

你可以试试这样的东西:

代码语言:javascript
复制
def custom_sort(population):
    pop_dict = { ind.ID: ind for ind in population }

    start = []
    nones = []
    end = []
    for ind in population:
        if ind.mate is None:
            nones.append(ind)
        elif pop_dict[ind.mate] not in start:
            start.insert(0, ind)
            end.append(pop_dict[ind.mate])
    return start + nones + end

这是假设“做配偶”是一种1比1的关系。

票数 5
EN

Stack Overflow用户

发布于 2013-08-26 16:01:27

您只需要为排序函数提供一个键。以下例子要求个人实行一夫一妻制,不与自己结婚。它还要求,如果(a,b)被列出,(b,a)也被列出。如果没有满足这些先决条件,并且没有Ind(1,2)就可以发生Ind(2,1),则此函数将将Ind(2,1)放置到列表的末尾。关键函数中的第一个索引是类型:关系中的“第一”(其中IDmate)排在第三位。这些第一和第二种类型是按照它们的ids排序的;最后一种类型是按其配偶的相反顺序排序的。

代码语言:javascript
复制
def keyfun(x):
   if x.mate==None: 
     return (1,x.ID)
   elif x.ID<x.mate: 
     return (0,x.ID)
   else:
     return (2,-x.mate)

sorted(population,key=keyfun)

处理这一问题的另一种方法,仍然假设(a,b)在列表(b,a)中,则只是预处理,删除(b,a)类,然后将它们按相反顺序添加回后处理。

票数 2
EN

Stack Overflow用户

发布于 2013-08-26 15:51:11

这个怎么样。将列表分成三个列表,一个使用ID < mate,第二个用ID > mate,第三个用mate is None。然后,将排序的列表连接起来,每个列表都通过ID排序。

为了提高输出的可读性,我向Ind类添加了一个Ind方法。

代码语言:javascript
复制
class Ind(object):
    def __init__(self,ID,mate):
        self.ID=ID
        self.mate=mate

    def __repr__(self):
        return 'Ind({},{})'.format(self.ID,self.mate)

population=[Ind(8,None), Ind(1,2), Ind(2,3), Ind(2,1), Ind(12,None), Ind(3,2), Ind(10,11), Ind(11,10)]

def custom_sort(pop):
    singles, less, more = [], [], []
    for p in pop:
        if p.mate is None:
            singles.append(p)
        elif p.ID < p.mate:
            less.append(p)
        elif p.ID > p.mate:
            more.append(p)
    comp = lambda x,y: cmp(x.ID,y.ID)
    return sorted(less,cmp=comp) + sorted(singles,cmp=comp) + sorted(more,cmp=comp,reverse=True)


print custom_sort(population)

这一产出如下:

代码语言:javascript
复制
[Ind(1,2), Ind(2,3), Ind(10,11), Ind(8,None), Ind(12,None), Ind(11,10), Ind(3,2), Ind(2,1)]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18447433

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档