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

时间:2015-01-19 17:19:29

标签: python sorting nested-lists

我有一个不同长度的嵌套列表,我希望按字母顺序按每个索引排序。可以这么说,我有:

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,而不会在嵌套列表中保留索引。

1 个答案:

答案 0 :(得分:1)

使用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    ]]