如果我有这样的嵌套列表:
L = [['James', '1', '2'], ['Alan', '1', '1'], ['Henry', '1', '5']]
如何根据每个子列表中的最后一个数字从最高到最低排序,而不使用排序或排序函数?
输出:
final = [['Henry', '1', '5'], ['James', '1', '2'], ['Alan', '1', '1']]
我知道如何做的唯一方法是使用排序功能,但我想知道如何在没有它的情况下做到这一点。
答案 0 :(得分:0)
L = [['James', '1', '2'], ['Alan', '1', '1'], ['Henry', '1', '5']]
keys = [(int(v[-1]),k) for k,v in enumerate(L)]
final = []
for i in range(len(keys)):
#find the next biggest element according to last element of the list.
final.append(L[max(keys)[-1]])
keys[max(keys)[-1]] = ''
final
Out[83]: [['Henry', '1', '5'], ['James', '1', '2'], ['Alan', '1', '1']]
答案 1 :(得分:0)
可以实施许多sorting algorithms。很久以前,蒂姆·彼得斯在Python sorted
内置thoughtfully implemented。
但是,这是另一个使用heapq
的排序选项:
import heapq
import operator as op
heapq.nlargest(len(L), L, key=op.itemgetter(-1))
# [['Henry', '1', '5'], ['James', '1', '2'], ['Alan', '1', '1']]
相比之下,请注意与sorted
的相似性,它有几个直观的选项:
import operator as op
expected = [['Henry', '1', '5'], ['James', '1', '2'], ['Alan', '1', '1']]
r1 = sorted(L, key=op.itemgetter(-1))[::-1]
r2 = sorted(L, key=op.itemgetter(-1), reverse=True)
r3 = list(reversed(sorted(L, key=op.itemgetter(-1))))
assert r1 == r2 == r3 == expected
sorted
通常很快,但有heapq
更快的例外情况。有关详细信息,另请参阅this post。
答案 2 :(得分:0)
您可以编写自己的quicksort功能。你几乎可以切换一些标志来反转输出:
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr)/2]
left = [x for x in arr if x > pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x < pivot]
return quicksort(left) + middle + quicksort(right)
下一步是确保你提取正确的数字,并确保你可以将它们映射回父列表,这样你就可以将它们放到正确的位置 - Allen's answer有一个好的的方法:
L = [['James', '1', '2'], ['Alan', '1', '1'], ['Henry', '1', '5']]
keys = [(int(v[-1]),k) for k,v in enumerate(L)] # This line here
该行基本上创建了一个元组列表,用于存储我们要排序的数字,以及该数字在父级列表中的父列表的索引。基本上,对于L
,keys = [(2, 0), (1, 1), (5, 2)]
。
因此,您可以通过创建可递归使用的子函数来更改quicksort
函数以解决所有这些问题:
def quicksort(arr):
# Put the actual sorting function into a subfunction that can be called recursively
def subsort(arr2):
if len(arr2) <= 1:
return arr2
pivot = arr2[len(arr2)/2]
left = [x for x in arr2 if x > pivot]
middle = [x for x in arr2 if x == pivot]
right = [x for x in arr2 if x < pivot]
return subsort(left) + middle + subsort(right)
# Get the value-key pairs and sort them
keys = [(int(v[-1]),k) for k,v in enumerate(L)]
keys = subsort(keys)
# Do the mapping back to the original array fed into the main function
final = []
for i in keys:
final.append(arr[i[1]])
return final
随之而来:
>>> L = [['James', '1', '2'], ['Alan', '1', '1'], ['Henry', '1', '5']]
>>> quicksort(L)
[['Henry', '1', '5'], ['James', '1', '2'], ['Alan', '1', '1']]
注意:如果在最后一个位置有两个具有相同编号的项目,那么这些项目将在原始列表中获得原始相对位置(相互之间)还原 。有关元组比较的更多详细信息,请参阅this answer,并注意我们在此处按降序顺序对事物进行排序(否则,它们只是保持原始位置相对于彼此)。所以:
>>> L = [['Simon', '1', '2'], ['Henry', '1', '5'], ['Finn', '1', '2']
>>> quicksort(L)
[['Henry', '1', '5'], ['Finn', '1', '2'], ['Simon', '1', '2']]