在 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)
) 是将行转换为列的好方法。然后对列进行排序并转换回来。唯一的问题是您无法将 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 ]]
我有一个不同长度的嵌套列表,我想按每个索引的字母顺序对其进行排序。也就是说,我有:
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)
) 是将行转换为列的好方法。然后对列进行排序并转换回来。唯一的问题是您无法将 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 ]]