有没有办法按"谓词"对字符串列表进行排序?清单吗?

时间:2016-02-28 06:06:14

标签: python

编辑:这个问题非常混乱。答案实际上比问题本身更好地解释了问题。

我有一个对象列表。

['BODY.H','BODY.VL','WHL0.H','BODY.M']

但是这个列表永远不会按照我想要的顺序排列。我想以这样的方式订购这些字符串

['BODY.H','BODY.M','BODY.VL','WHL0.H']

BODY.H始终位于索引0处,BODY.M始终位于索引1处,等等。

有没有办法可以根据各种谓词列表对列表进行排序? (例如['BODY.H','BODY.M'])。我还没有尝试任何东西,因为我不知道从哪里开始。

2 个答案:

答案 0 :(得分:1)

(您已将问题更改为想要使用字符串而不是使用对象,因此此示例使用字符串。)

使用谓词列表中每个字符串的索引来提供要对给定列表进行排序的key

>>> wanted_order = ['BODY.H', 'BODY.M', 'BODY.VL', 'WHL0.H']
>>> got_list = ['WHL0.H', 'BODY.H', 'BODY.VL', 'BODY.VL', 'WHL0.H', 'BODY.M']
>>> sorted(got_list, key=lambda s: wanted_order.index)
['BODY.H', 'BODY.M', 'BODY.VL', 'BODY.VL', 'WHL0.H', 'WHL0.H']

请注意,我在got_list中添加了一些额外的重复项,以说明它如何与通用输入一起使用,以及每个项目的多个项目。

顺便说一句,如果总是只有这4个对象,为什么不用这4个创建一个列表呢?

此外,如果谓词中缺少字符串,则会出错。所以也许把它放在一个函数(而不是一个lambda)中,如果它发生就捕获该错误,并返回另一个值。

修改

对于您想要的对象版本,您可以使用s.name作为键和谓词(当然,wanted_order具有对象的名称):

>>> sorted(got_list, key=lambda s: wanted_order.index(s.name))

编辑2:

要处理got_listwanted_order中没有'姓名'的项目:

>>> def predicated_key(item):
...     wanted_order = ['BODY.H', 'BODY.M', 'BODY.VL', 'WHL0.H']
...     # put wanted_order in global scope if you prefer instead of here
...     try:
...         return wanted_order.index(item)  # or item.name in your case
...     except ValueError:
...         return len(wanted_order)  # since this will be higher than the
...                                   # index of the any item on the list
...
>>> got_list = ['WHL0.H', 'BODY.H', 'something', 'BODY.VL',
...             'something else', 'BODY.VL', 'WHL0.H', 'BODY.M']
>>> sorted(got_list, key=predicated_key)
['BODY.H', 'BODY.M', 'BODY.VL', 'BODY.VL', 'WHL0.H', 'WHL0.H', 'something', 'something else']

答案 1 :(得分:0)

对于最初问题的混淆,我们深表歉意。当我想到它时,我最终搞清楚了:)

def reorder_object_list(lst,pred):
return_list = [None] * len(pred)
for v in lst:
    try:
        return_list[pred.index(v)] = v
    except:
        #not found in predicate list 
        return_list.append(v)
return [x for x in return_list if x != None]

list = ["HLIGHT_L","BODY_H","BODY_VL","TLIGHT_L","BODY_M"]
pred = ["BODY_H","BODY_M","BODY_VL","HLIGHT_L","TLIGHT_L"]
reordered = reorder_list(list,pred)
for v in reordered:
    print(v)