我有一份清单如下:
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的个体在mate属性中有None。说得通吗?
我想对这个列表进行排序,以便第一个个体和最后一个个体,第二个个体和第二个到最后一个个体,等等.属性为mate等于None的个人应该站在列表的中间。
有许多可能的输出符合我的要求。以下是上述列表中这些输出的一个示例:
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)]发布于 2013-08-26 15:29:21
你可以试试这样的东西:
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的关系。
发布于 2013-08-26 16:01:27
您只需要为排序函数提供一个键。以下例子要求个人实行一夫一妻制,不与自己结婚。它还要求,如果(a,b)被列出,(b,a)也被列出。如果没有满足这些先决条件,并且没有Ind(1,2)就可以发生Ind(2,1),则此函数将将Ind(2,1)放置到列表的末尾。关键函数中的第一个索引是类型:关系中的“第一”(其中IDmate)排在第三位。这些第一和第二种类型是按照它们的ids排序的;最后一种类型是按其配偶的相反顺序排序的。
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)类,然后将它们按相反顺序添加回后处理。
发布于 2013-08-26 15:51:11
这个怎么样。将列表分成三个列表,一个使用ID < mate,第二个用ID > mate,第三个用mate is None。然后,将排序的列表连接起来,每个列表都通过ID排序。
为了提高输出的可读性,我向Ind类添加了一个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)]https://stackoverflow.com/questions/18447433
复制相似问题