Python 使用对象列表对嵌套列表进行排序

Python 使用对象列表对嵌套列表进行排序,python,list,sorting,nested,Python,List,Sorting,Nested,您好,我正在尝试找出如何按多个变量对嵌套列表进行排序,而有些不会按1、2、3进行排序,而是按预定列表进行排序 例如: List=[[XD,1],[XD,3],[XD,2],[X5,2],[X5,3],[XT,2]] 这将导致: [[XD,1],[XD,2],[XD,3],[XT,2],[X5,2],[X5,3]] 第一个元素将按sortbylist排序,第二个元素仅按数字顺序排序 SortByList={'XD': 'A', 'XT':'B', 'XQ': 'C','X5': 'D'} 我

您好,我正在尝试找出如何按多个变量对嵌套列表进行排序,而有些不会按1、2、3进行排序,而是按预定列表进行排序

例如:

List=[[XD,1],[XD,3],[XD,2],[X5,2],[X5,3],[XT,2]]
这将导致:

[[XD,1],[XD,2],[XD,3],[XT,2],[X5,2],[X5,3]]
第一个元素将按sortbylist排序,第二个元素仅按数字顺序排序

SortByList={'XD': 'A', 'XT':'B', 'XQ': 'C','X5': 'D'}
我目前正在尝试使用以下代码:

List.sort(key=SortByList.__getitem__  x: x[0])
List=sorted(List,key=itemgetter(1))
然而,这似乎不起作用。有什么提示吗

最简单的方法之一是:

Result=sorted(List, key=lambda x:(SortByList[x[0]],x[1]))
那么:

In [2]: List=[['XD',1],['XD',3],['XD',2],['X5',2],['X5',3],['XT',2]]

In [3]: SortByList={'XD': 'A', 'XT':'B', 'XQ': 'C','X5': 'D'}

In [4]: sorted(List, key=lambda x:(SortByList[x[0]],x[1]))
Out[4]: [['XD', 1], ['XD', 2], ['XD', 3], ['XT', 2], ['X5', 2], ['X5', 3]]
如您的问题所述,它使用两元素复合键。

如何:

In [2]: List=[['XD',1],['XD',3],['XD',2],['X5',2],['X5',3],['XT',2]]

In [3]: SortByList={'XD': 'A', 'XT':'B', 'XQ': 'C','X5': 'D'}

In [4]: sorted(List, key=lambda x:(SortByList[x[0]],x[1]))
Out[4]: [['XD', 1], ['XD', 2], ['XD', 3], ['XT', 2], ['X5', 2], ['X5', 3]]

这使用了一个两元素复合键,如您的问题中所述。

这里的问题是,您试图使用对象的名称对对象进行排序,以获得排序顺序,但您的对象没有任何对其名称的引用。除非在
locals()
globals()
中搜索,否则无法从对象
XD
判断它是否被称为
'XD'

这里最好的选择是将变量存储在字典中,而不是直接存储在作用域/命名空间中。因此,请从此处更改您的代码:

XD = MyObject(...)
X5 = MyObject(...)
XT = MyObject(...)
List=[[XD,1],[XD,3],[XD,2],[X5,2],[X5,3],[XT,2]]
为此:

XDict = {'XD': MyObject(...),
         'X5': MyObject(...),
         'XT': MyObject(...)}
List = [[XDict['XD'],1],[XDict['XD'],3],[XDict['XD'],2],
        [XDict['X5'],2],[XDict['X5'],3],[XDict['XT'],2]]
列表
的内容将完全相同,但现在您可以将名称
'XD'
'X5'
'XT'
与对象相关联,因此在定义
排序列表
时,您可以根据实际对象的名称创建一个列表:

SortByList=[XDict.get('XD'), XDict.get('XT'), XDict.get('XQ'), XDict.get('X5')]
sorted(List, key=lambda k, i: (SortedByList.index(k), i))

通过这种方式,您可以创建
SortByList
,即使某些变量未定义,如本例中的
XQ
SortByList
中的条目只会是
None
,这在对其他元素进行排序时不会引起任何问题。

这里的问题是,您试图使用对象的名称对对象进行排序,以获得排序顺序,但您的对象没有对其名称的任何引用。除非在
locals()
globals()
中搜索,否则无法从对象
XD
判断它是否被称为
'XD'

这里最好的选择是将变量存储在字典中,而不是直接存储在作用域/命名空间中。因此,请从此处更改您的代码:

XD = MyObject(...)
X5 = MyObject(...)
XT = MyObject(...)
List=[[XD,1],[XD,3],[XD,2],[X5,2],[X5,3],[XT,2]]
为此:

XDict = {'XD': MyObject(...),
         'X5': MyObject(...),
         'XT': MyObject(...)}
List = [[XDict['XD'],1],[XDict['XD'],3],[XDict['XD'],2],
        [XDict['X5'],2],[XDict['X5'],3],[XDict['XT'],2]]
列表
的内容将完全相同,但现在您可以将名称
'XD'
'X5'
'XT'
与对象相关联,因此在定义
排序列表
时,您可以根据实际对象的名称创建一个列表:

SortByList=[XDict.get('XD'), XDict.get('XT'), XDict.get('XQ'), XDict.get('X5')]
sorted(List, key=lambda k, i: (SortedByList.index(k), i))

通过这种方式,您可以创建
SortByList
,即使某些变量未定义,如本例中的
XQ
SortByList
中的条目只会是
None
,这在对其他元素进行排序时不会导致任何问题。

直接在python中运行它时,效果非常好。然而,当你把它放在一个程序中时,它似乎并没有对列表进行排序。有什么想法吗?@Ophion:这段代码只是打印出结果;它不会将其分配回
列表
。要么将其更改为
List=sorted(List,key=…)
,要么使用
List.sort(key=…)
。直接在python中运行它时,效果非常好。然而,当你把它放在一个程序中时,它似乎并没有对列表进行排序。有什么想法吗?@Ophion:这段代码只是打印出结果;它不会将其分配回
列表
。要么将其更改为
List=sorted(List,key=…)
,要么使用
List.sort(key=…)
。我希望有一个更简单的答案。如果aix的建议不起作用,我将使用它。谢谢你的意见。我希望有一个更简单的答案。如果aix的建议不起作用,我将使用它。谢谢你的意见。