Python:如何自定义列表顺序?
Obs:我知道python中的列表不是顺序固定的,但我认为这一个是固定的。 我使用的是Python 2.4 我有一个列表,比如:Python:如何自定义列表顺序?,python,list,sorting,Python,List,Sorting,Obs:我知道python中的列表不是顺序固定的,但我认为这一个是固定的。 我使用的是Python 2.4 我有一个列表,比如: mylist = [ ( u'Article', {"...some_data..."} ) , ( u'Report' , {"...some_data..."} ) , ( u'Book' , {"...another_data..."} ) , ...#continue ] 此变量mylist是从函数
mylist = [ ( u'Article', {"...some_data..."} ) ,
( u'Report' , {"...some_data..."} ) ,
( u'Book' , {"...another_data..."} ) ,
...#continue
]
此变量mylist是从函数中获取的,返回列表的“顺序”会有所不同。所以,有时候会像这个例子一样。有时,“报告”会出现在“文章”之前,等等
我有一个固定的顺序,我想在这个名单上(不是字母顺序)
假设我的固定顺序是:“报告”、“文章”、“书”
所以,我想要的是:无论“mylist”实例化的顺序是什么,我都想重新排序,使“Report”保持在前面,“Article”保持在第二位,等等
使用“自定义”顺序对列表重新排序(取列表中每个项目元组的第一个元素)的最佳方法是什么
回答:
我的结论是:mylist变成了一个目录,如下所示:
mylist = [{'id':'Article', "...some_data..."} ,
...etc
]
mydict = { u'Article': "somedata",
u'Report': "someotherdata", ...}
每个dict都有一个必须排序的“id”
在列表上保存正确的顺序在列表上分配正确的顺序:
correct_order = ['Report', 'Article', 'Book', ...]
并且做:
results = sorted([item for item in results], cmp=lambda x,y:cmp(correct_order.index(x['id']), correct_order.index(y['id'])))
你可以使用字典,这样你就可以访问“书”、“文章”等,而不必关心顺序。我会将该列表中的数据放入一个dict,如下所示:
mylist = [{'id':'Article', "...some_data..."} ,
...etc
]
mydict = { u'Article': "somedata",
u'Report': "someotherdata", ...}
如果您确实希望按照所描述的方式对列表进行排序,则可以使用
list.sort
和表示特定排序顺序的键函数()。您需要键函数,因为您只需要访问第一个元素,并且排序顺序也不是字母顺序。您可以使用一个字典,将每个第一个元素映射到其“权重”,然后在排序函数中检查该字典
比如:
d = { "Report": 1,
"Article": 2,
"Book": 3 }
result = sorted(mylist, key=lambda x:d[x[0]])
这样创建一个dict并按顺序从中提取项目
mylist = [ ( u'Article', {"...some_data..."} ) ,
( u'Report' , {"...some_data..."} ) ,
( u'Book' , {"...another_data..."} ) ,
]
mydict = dict(mylist)
ordering = [u'Report', u'Article', u'Book']
print [(k,mydict[k]) for k in ordering]
这种方式使用sort with O(1)查找排序
mylist = [ ( u'Article', {"...some_data..."} ) ,
( u'Report' , {"...some_data..."} ) ,
( u'Book' , {"...another_data..."} ) ,
]
mydict = dict(mylist)
ordering = dict((k,v) for v,k in enumerate([u'Report', u'Article', u'Book']))
print sorted(mydict.items(), key=lambda (k,v): ordering[k])
更一般地说,mylist中的某些元素可能不符合指定的固定顺序。这将根据规则进行排序,但不考虑规则之外所有事物的相对顺序:
def orderListByRule(alist,orderRule,listKeys=None,dropIfKey=None):
###
#######################################################################################
""" Reorder alist according to the order specified in orderRule. The orderRule lists the order to be imposed on a set of keys. The keys are alist, if listkeys==None, or listkeys otherwise. That is, the length of listkeys must be the same as of alist. That is, listkeys are the tags on alist which determine the ordering. orderRule is a list of those same keys and maybe more which specifies the desired ordering.
There is an optional dropIfKey which lists keys of items that should be dropped outright.
"""
maxOR = len(orderRule)
orDict = dict(zip(orderRule, range(maxOR)))
alDict = dict(zip(range(maxOR, maxOR+len(alist)),
zip(alist if listKeys is None else listKeys, alist)))
outpairs = sorted( [[orDict.get(b[0],a),(b)] for a,b in alDict.items()] )
if dropIfKey is None: dropIfKey=[]
outL = [b[1] for a,b in outpairs if b[0] not in dropIfKey]
return outL
def test_orderListByRule():
L1 = [1,2,3,3,5]
L2 = [3,4,5,10]
assert orderListByRule(L1, L2) == [3, 3, 5, 1, 2]
assert orderListByRule(L1, L2, dropIfKey=[2,3]) == [5, 1,]
Lv = [c for c in 'abcce']
assert orderListByRule(Lv, L2, listKeys=L1) == ['c', 'c', 'e', 'a', 'b']
assert orderListByRule(Lv, L2, listKeys=L1, dropIfKey=[2,3]) == ['e','a']
此函数通过自定义列表进行排序,但如果列表中没有任何元素,则不会生成错误。但是,此元素将位于行的末尾
def sort_custom(ordem_custom : list , origin : list) -> list:
list_order_equals = [c for c in ordem_custom if (c in origin)]
list_no_equals = [c for c in origin if (not c in ordem_custom)]
list_order = list_order_equals + list_no_equals
return list_order
#例
最好使用键函数,而不是Python3中不再存在的不推荐使用的cmp函数:
sorted(mylist,key=lambda x:d[x[0]])
还没有尝试Python3,所以我不知道。。谢谢:)这也是Python2的建议,因为使用键函数比使用cmp函数快。你也可以这样写:d=[“报告”、“文章”、“书”]
然后result=sorted(mylist,key=lambda x:d.index(x[0])
同样,这个链接在这个问题上是最有用的!