我正在尝试按第一行对Python中的列表列表进行排序(特别是不使用Numpy,我知道有很多使用Numpy的解决方案,但这是一个专门要求不使用Numpy的方法的问题)
这是我的清单清单:
1
2
3listOfLists = [ ['m', 'e', 'l', 't', 's'],
['g', 'p', 's', 'k', 't'],
['y', 'q', 'd', 'h', 's'] ]
我正在寻找仅按第一个列表项对列表进行排序1)按字母顺序排序但2),垂直切片应仅遵循第一个列表项的顺序。例如:
1
2
3newListofLists = [ ['e', 'l', 'm', 's', 't'],
['p', 's', 'g', 't', 'k'],
['q', 'd', 'y', 's', 'h'] ]
listOfLists中的第一项是" melts",然后按字母顺序排序为" elmst"。列表列表中的其余项目不是按字母顺序排序的,而是"遵循"列表中第一项的开关和排序方式。
我可能很荒谬,但是我已经花了几个小时解决这个问题(这是一个较大的程序的一部分)。我尝试将列表中的第一项切片,然后按字母顺序对其进行排序,然后将其与尚未排序的列表中的第一项列表进行比较,并比较位置。但是我似乎什么也做不了。
为什么不允许numpy?
您可以使用zip转置列表,对转置进行排序,然后将该列表转回正确的尺寸之一。
1
2
3
4
5
6listOfLists = [ ['m', 'e', 'l', 't', 's'],
['g', 'p', 's', 'k', 't'],
['y', 'q', 'd', 'h', 's'] ]
print(list(zip(*sorted(zip(*listOfLists)))))
# [('e', 'l', 'm', 's', 't'), ('p', 's', 'g', 't', 'k'), ('q', 'd', 'y', 's', 'h')]
编辑:
正如@StevenRumbalski在评论中指出的那样,以上内容将完全对垂直切片进行排序(按第一个字母,第二个字母等),而不是按输入的第一个字母稳定地对其进行排序(按第一个字母排序,然后按相对顺序排序) )。 我将在此处重现他的解决方案以提高知名度:
1
2from operator import itemgetter
list(map(list, zip(*sorted(zip(*listOfLists), key=itemgetter(0)))))
还有一个仍然需要满足的额外要求:"但是2)仅第一个列表项有效,垂直切片应仅遵循第一个列表项的顺序。"通过在sorted()中添加关键参数来解决:from operator import itemgetter; list(map(list, zip(*sorted(zip(*listOfLists), key=itemgetter(0)))))(我还假定他仍然想要列表的列表,因此我将外部list(...)转换为list(map(list, ...))。)
@StevenRumbalski那就是如何对元组进行排序。您会注意到,您的解决方案和我的解决方案具有相同的输出。唯一的区别是您的解决方案是一种稳定的解决方案,而我的解决方案则不是。由于OP没有指定,Im倾向于认为这不是必需的。
我引用了OP给出的要求。还可以看到标题上写着"还有其他列表遵循交换顺序"。关注和影响之间是有区别的。给定[[b, a, b], [z, x, a]]的原始列表,我认为基于OP的描述,[[a, b, b], [x, a, z]]的结果不正确,应该为[[a, b, b], [x, z, a]]。压缩后的元素应随身携带,而不是后座驾驶员。
最后一个例子,病态了,我同意不同意。起始列表[[a,a],[n,m],[x,y]]和起始列表[[a,a],[x,y],[n,m]]将根据行顺序以不同的顺序结束。所以我的意思是行顺序不重要。第一行是确定排序顺序的键值。任何渗漏都违反了该问题。病态引用了问题的第三部分"列表中的其余项没有按字母顺序排序,而是遵循列表中第一项的切换和排序方式。"
numpy是提高性能和可读性的方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14import numpy as np
listOfLists = [ ['m', 'e', 'l', 't', 's'],
['g', 'p', 's', 'k', 't'],
['y', 'q', 'd', 'h', 's'] ]
lol = np.array(listOfLists)
lol[:, np.argsort(listOfLists[0])]
# array([['e', 'l', 'm', 's', 't'],
# ['p', 's', 'g', 't', 'k'],
# ['q', 'd', 'y', 's', 'h']],
# dtype='
非numpy解决方案:
1
2
3idx = sorted(range(len(lol[0])), key=lol[0].__getitem__)
[list(map(lol[j].__getitem__, idx)) for j in range(len(lol))]
OP不想使用Numpy
感谢您抽出宝贵的时间来提出解决方案,但是很遗憾,对于这个特定的问题,我不想使用Numpy
那么为何不...?