在 Python 中对可变长度的嵌套列表进行排序

Sorting nested lists of variable length in Python

我有一个不同长度的嵌套列表,我想按每个索引的字母顺序对其进行排序。也就是说,我有:

a = [['header1', 'header2', 'header3'],
     ['apple',   'pear',    'banana' ],
     ['pear',    'banana',  'orange' ],
     ['kiwi',     None,     'apple'  ],
     ['peach',    None,      None   ]]

我想要一个输出以下内容的操作:

a = [['header1', 'header2', 'header3'],
     ['apple',   'banana',  'apple'  ],
     ['kiwi',    'pear',    'banana' ],
     ['peach',    None,     'orange' ],
     ['pear',     None,      None   ]]

我尝试使用嵌套的 for 循环遍历并为特定索引创建临时值列表,然后排序然后重新添加,但是似乎出现索引错误(可能是由于 None 值)?

最好了解嵌套循环是否是执行此操作的最有效方法。我最初使用 itemgetter 对嵌套列表进行排序,但后来不得不转置它们,并使用 map(lambda *row: list(row), *a) 这样做 - 虽然这并没有保留我的顺序。

据我所知,如果不保留跨嵌套列表的索引,我无法在现在转置的嵌套列表上使用 itemgetter

使用 zip splats (zip(*a)) 是将行转换为列的好方法。然后对列进行排序并转换回来。唯一的问题是您无法将 Nonestr 进行比较,因此您必须定义一些自定义排序算法,例如:

def sorter(char):
    if char is None:
        return chr(0x101111) # largest character
        # this is certainly a kludge solution, but I can't
        # find a better one in the minimal time I have to research
        # hopefully comments will find better!
    else:
        return char

a = [['header1', 'header2', 'header3'],
     ['apple',   'pear',    'banana' ],
     ['pear',    'banana',  'orange' ],
     ['kiwi',     None,     'apple'  ],
     ['peach',    None,      None    ]]

a_headers, a_rows = a[0], a[1:]
a_to_columns = list(zip(*a_rows))
sorted_a_columns = [sorted(lst, key=sorter) for lst in a_to_columns]
result = [a_headers] + list(map(list, zip(*sorted_a_columns))))

>>> pprint(result)

[['header1', 'header2', 'header3'],
 ['apple'  , 'banana' , 'apple'  ],
 ['kiwi'   , 'pear'   , 'banana' ],
 ['peach'  ,  None    , 'orange' ],
 ['pear'   ,  None    ,  None    ]]