Python:如何自定义列表?

时间:2010-09-02 06:36:06

标签: python list sorting

Obs:我知道python中的列表不是按顺序修复的,但认为这个列表是。 我正在使用Python 2.4

我有一个列表,比如(例如)这个:

mylist = [ ( u'Article', {"...some_data..."}    ) ,
           ( u'Report' , {"...some_data..."}    ) ,
           ( u'Book'   , {"...another_data..."} ) ,
...#continue
]

此变量mylist是从函数中获取的,返回列表的“顺序”会有所不同。所以,有时它就像在例子上。有时,“报告”将出现在“文章”等之前。

我在此列表中有一个我想要的固定订单(并不是按字母顺序排列)。

让我们说我的固定订单是:'报告','文章','预订',...

所以,我想要的是:无论命令'mylist'被实例化,我都要重新排序,让'Report'保持在前面,'Article'在第二,等等......

使用我的“自定义”订单重新排序列表(使用列表中每个项目的元组的第一个元素)的最佳方法是什么?

答案

我最终得到了这个:

mylist成了一个dicts列表,如下所示:

mylist = [{'id':'Article', "...some_data..."} ,
        ...etc
]

每个dict都有一个必须排序的'id'。

在列表中保存正确的顺序在列表中分配correct_order:

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'])))

5 个答案:

答案 0 :(得分:16)

您可以使用将每个第一个元素映射到其“权重”的字典,然后在排序函数中检查此字典。

类似的东西:

d = { "Report": 1,
      "Article": 2,
       "Book": 3 }
result = sorted(mylist, key=lambda x:d[x[0]])

答案 1 :(得分:6)

您可以使用字典,这样您就可以访问“Book”,“Article”等,而无需关心订单。我会将该列表中的数据放入一个如下所示的字典中:

mydict = { u'Article': "somedata",
           u'Report': "someotherdata", ...}

如果您真的想按照描述的方式对列表进行排序,可以使用list.sort和一个代表您特定排序顺序的关键函数(Documentation)。您需要键功能,因为您只需要访问第一个元素,而您的排序顺序也不是按字母顺序排列的。

答案 2 :(得分:2)

这种方式创建一个字典并按顺序从中拉出项目

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]

这种方式使用排序与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])

答案 3 :(得分:1)

更一般地说,可能存在不在指定的固定顺序中的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']

答案 4 :(得分:0)

此函数对自定义列表进行排序,但如果列表中没有任何元素,则不会生成错误。但是,该元素将位于行尾。

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

#例子

custom_order = ('fa','a','b','c','d','e')
my_list =  ('e','c','fa','h','h','g')

result = sort_custom(custom_order,my_list)
print(result)