Python:如何自定义列表顺序?

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是从函数

Obs:我知道python中的列表不是顺序固定的,但我认为这一个是固定的。 我使用的是Python 2.4

我有一个列表,比如:

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])
同样,这个链接在这个问题上是最有用的!