[英]How to sort list by using specific rules
嗨,我有一些复杂的数据对象,我想对它们进行排序。 下面的简化版本:
class Data(object):
def __init__(self, s):
self.s = s
每个数据对象都将放置在特定类别中,以便以后使用。 简化的版本再次在下面
class DataCategory(object):
def __init__(self, id1, id2, linked_data=None):
self.id1 = id1
self.id2 = id2
self.ld = linked_data
我想按以下编号对数据进行排序,但还有更多规则。 如果从第一个数据收集中使用了一个数据对象,那么我想从第二个收集中使用一个数据对象,如果s的数量相同或更低。 这就是我得到的以及我想要实现的
# order I get
# [['p02g01r05', 5], ['p02g01r01', 4], ['p01g01r05', 4], ['p01g01r01', 3], ['p01g01r02', 2], ['p01g01r03', 2], ['p01g01r06', 2], ['p02g01r02', 2], ['p02g01r03', 2], ['p02g01r04', 2], ['p01g01r04', 1], ['p02g01r06', 1]]
# order I want
# [['p02g01r05', 5], ['p01g01r05', 4], ['p02g01r01', 4], ['p01g01r01', 3], ['p02g01r02', 2], ['p01g01r02', 2], ['p02g01r03', 2], ['p01g01r03', 2], ['p02g01r04', 2], ['p01g01r06', 2], ['p02g01r06', 1]], ['p01g01r04', 1]
到目前为止,这是我创建的,但是我认为我朝这个方向走了。 我认为要替换的索引列表是正确的。
# Some data objects
p01g01r01 = Data(3)
p01g01r02 = Data(2)
p01g01r03 = Data(2)
p01g01r04 = Data(1)
p01g01r05 = Data(4)
p01g01r06 = Data(2)
p02g01r01 = Data(4)
p02g01r02 = Data(2)
p02g01r03 = Data(2)
p02g01r04 = Data(2)
p02g01r05 = Data(5)
p02g01r06 = Data(1)
p01g01 = DataCategory("01", "01", [])
p02g01 = DataCategory("02", "01", [])
# link data to data category
def ldtdc(dc):
lst = []
data = "p" + dc.id1 + "g" + dc.id2 + "r"
for i in range(1, 7):
if i < 10:
lst.append(data + "0" + str(i))
else:
lst.append(data + str(i))
return lst
p01g01.ld = ldtdc(p01g01)
p02g01.ld = ldtdc(p02g01)
# /@= This starts to get way too complicated fast ############################
def lstu(ag, dg):
lst = []
# data list of first collection
dlofc = []
# data list of second collection
dlosc = []
# for every data unit that exists in data collection
for unit in ag.ld:
# lst.append([unit, globals()[unit].s+10])
lst.append([unit, globals()[unit].s])
dlofc.append([unit, globals()[unit].s])
for unit in dg.ld:
lst.append([unit, globals()[unit].s])
dlosc.append([unit, globals()[unit].s])
# lambda function is used here to sort list by data value ([1] is index of the item)
lst = sorted(lst, key=lambda x: x[1], reverse=True)
# current index
ci = 0
previous_data = ["last data unit will be stored here", 0]
# sorted list
slst = []
for unit in lst:
try:
next_data = lst[ci+1]
except IndexError:
next_data = ["endoflist", 0]
if previous_data[0] == "last data unit will be stored here":
pass
elif previous_data[0][:6] == unit[0][:6]:
if unit[0][:6] not in dlofc[0][0]:
slst.append([unit[0], unit[1], ci])
elif unit[0][:6] not in dlosc[0][0]:
slst.append([unit[0], unit[1], ci])
else:
print "Error"
previous_data = unit
ci += 1
print "slist below"
print slst
return lst
# \@= END #####################################################################
print p01g01.ld
print p02g01.ld
data_list = lstu(p01g01, p02g01)
print data_list
排序此数据的快速正确的方法是什么?
您是否尝试过先按字符串排序,然后按项目中的数字排序?
>>> items = [['p02g01r05', 5], ['p02g01r01', 4], ['p01g01r05', 4], ['p01g01r01', 3], ['p01g01r02', 2], ['p01g01r03', 2], ['p01g01r06', 2], ['p02g01r02', 2], ['p02g01r03', 2], ['p02g01r04', 2], ['p01g01r04', 1], ['p02g01r06', 1]]
>>> partially_sorted = sorted(items, key=lambda item: item[0], reverse=True)
>>> sorted(partially_sorted, key=lambda item: item[1], reverse=True)
[['p02g01r05', 5], ['p02g01r01', 4], ['p01g01r05', 4], ['p01g01r01', 3], ['p02g01r04', 2], ['p02g01r03', 2], ['p02g01r02', 2], ['p01g01r06', 2], ['p01g01r03', 2], ['p01g01r02', 2], ['p02g01r06', 1], ['p01g01r04', 1]]
找到解决方案。 新的lstu函数:
# replaced lambda with normal function
def get_key(item):
return item[1]
def lstu(ag, dg):
# ag list
agslst = []
# dg list
dgslst = []
# for every unit in first data collection
for unit in ag.u:
agslst.append([unit, globals()[unit].s])
# sorted first data collection list
agslst = sorted(agslst, key=get_key, reverse=True)
print agslst
for unit in dg.u:
dgslst.append([unit, globals()[unit].s])
# 2nd collection sorted list
dgslst = sorted(dgslst, key=get_key, reverse=True)
print dgslst
lst = []
# last item
li = ["Empty", 0]
for item in range(0, len(agslst)+len(dgslst)+1):
if agslst and dgslst:
if agslst[0][1] == dgslst[0][1]:
if li[0][:6] == agslst[0][0][:6]:
li = dgslst.pop(0)
lst.append(li)
else:
li = agslst.pop(0)
lst.append(li)
elif agslst[0][1] > dgslst[0][1]:
li = agslst.pop(0)
lst.append(li)
else:
li = dgslst.pop(0)
lst.append(li)
return lst
这样,我就可以满足前面提到的新(和最终)清单的要求
输出:
[['p02g01r05', 5], ['p01g01r05', 4], ['p02g01r01', 4], ['p01g01r01', 3], ['p02g01r02', 2], ['p01g01r02', 2], ['p02g01r03', 2], ['p01g01r03', 2], ['p02g01r04', 2], ['p01g01r06', 2], ['p02g01r06', 1]], ['p01g01r04', 1]]
我愿意接受任何优化建议。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.