我有以下类型的列表:
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
!因此,如果Ind
的实例ID
等于12且mate
等于34,那么列表中必须有一个ID
等于34且其mate
等于12.没有mate
的个人None
属性中有mate
。它有意义吗?
我想对这个列表进行排序,以便第一个人与最后一个人交配,第二个人与倒数第二个人交配,等等......属性mate
的个人等于{ {1}}应该位于列表的中间位置。
有许多可能的输出符合我的要求。以下是上述列表中这些输出的一个示例:
None
答案 0 :(得分:5)
您可以尝试这样的事情:
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 :(得分:2)
您只需要一个用于排序功能的键。以下示例要求个人是一夫一妻制而不是与自己结婚。它还要求列出if(a,b),(b,a)也列出。如果不满足这些先决条件并且Ind(2,1)可以在没有Ind(1,2)的情况下发生,则此函数将Ind(2,1)放在列表的末尾。关键函数中的第一个索引是类型:关系中的“first”(IDmate)排在第三位。这些第一和第二类型按其ID排序;最后一种类型由其配偶以相反的顺序排序。
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)
另一种处理这个的方法,仍然假设if(a,b)在列表中(b,a)也将在列表中,只是通过删除(b,a)个案进行预处理,然后进行后处理将它们以相反的顺序重新添加。
答案 2 :(得分:0)
这个怎么样?将列表拆分为三个列表,一个列表为ID < mate
,第二个列表为ID > mate
,第三个列表为mate is None
。然后,连接已排序的列表,每个列表通过ID进行排序。
我在__repr__
类中添加了Ind
方法,以提高输出可读性。
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)
输出:
[Ind(1,2), Ind(2,3), Ind(10,11), Ind(8,None), Ind(12,None), Ind(11,10), Ind(3,2), Ind(2,1)]
答案 3 :(得分:0)
使用自定义键功能可以做很多事情:
def my_key(ind):
if ind.mate is None:
return 0
if ind.ID < ind.mate:
return -ind.ID - 1
else:
return ind.mate + 1
population.sort(key=my_key)
这假设ID永远不会是负数。如果ID始终大于0,您可以放弃- 1
和+ 1
。