我有一个不同长度的嵌套列表,我希望按字母顺序按每个索引排序。可以这么说,我有:
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
,而不会在嵌套列表中保留索引。
答案 0 :(得分:1)
使用zip splats(zip(*a)
)是将行转换为列的好方法。然后对列进行排序并转换回来。唯一的问题是您无法将None
与str
进行比较,因此您必须定义一些自定义排序算法,例如:
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 ]]