如何使用python对复杂列表进行排序?

时间:2018-10-26 07:40:34

标签: python python-3.x sorting

输入列表

lst = [311, 409, 305, 104, 301, 204, 101, 306, 313, 202, 303, 410, 401, 105, 407, 408]

不期望的输出(lst.sort()):

[101, 104, 105, 202, 204, 301, 303, 305, 306, 311, 313, 401, 407, 408, 409, 410]

预期输出:

[101, 301, 401, 202, 303, 104, 204, 105, 305, 306, 407, 408, 409, 410, 311, 313]

最后两位数字升序排列,而第一位数字升序排列。我不确定如何处理这种情况。我尝试使用lst.sort(),但这不能完成工作。我已经研究了其他实现密钥的帖子,但是我以前从未使用过,并且不知道如何在此代码中实现。

4 个答案:

答案 0 :(得分:0)

如果您想要的是输出[101,301,401,202,303,104,204,105,305,306,407,408,409,410,311,313],则可以使用以下内容:

def my_key(x):
    return x%100, x/100


print(sorted(lst, key=my_key))

或具有lambda函数:

print(sorted(lst, key=lambda x: (x%100, x/100))

答案 1 :(得分:0)

这可以完成工作:

lst.sort(key=lambda x: str(x)[1:] + str(x)[0])

输出:

[101, 301, 401, 202, 303, 104, 204, 105, 305, 306, 407, 408, 409, 410, 311, 313]

此外,正如 @gdelab 正确说的那样,您可以使用除法来实现:

lst.sort(key=lambda x: (x % 100, x / 100))

说明

str(x)[1:] + str(x)[0] 创建一个字符串,该字符串以后两位数字开头(假设您的电话号码始终为3位数字),然后以第一位数字结尾。因此它映射为:311->'113',依此类推,然后按您需要的顺序获取数字。

答案 2 :(得分:0)

似乎不清楚您要问什么。听起来您标题的含义更接近于“如何在Python中按自定义排序顺序进行排序?”

这是我对您的问题的重申。如果不正确,那么我的答案也将是错误的。

I want to sort a list in a special way.  Each item is a three digit number and I want to sort by the last two digits, then by the first digit.  That is, I want to do something like this:

 > my_list=[311, 409, 305, 104, 301, 204, 101, 306, 313, 202, 303, 410, 401, 105, 407, 408]
 > my_list.sort()
 > print(my_list)
 [101,301,401,202,303,104,204,105,305,306,407,408,409,410,311,313]

也就是说,这里有一些想法:

  • 这个问题可能是相关的:Python: How to custom order a list?
  • 自定义排序需要您创建一个正常排序的临时值。也就是说,您为每个输入输入一个中间值并对中间值进行排序。
  • (305 % 100)*10 + 305 // 100等于5*10+353
  • 一起,您将获得print(sorted(my_list, key=lambda x: (x % 100) * 10 + x // 100))

尝试真正理解为什么这行得通;类似的问题是传统的作业问题。

答案 3 :(得分:0)

纯Python解决方案是先使用模数(%)运算符排序,然后再使用地板除法(//)运算符排序:

L = [311, 409, 305, 104, 301, 204, 101, 306, 313, 202, 303, 410, 401, 105, 407, 408]

res = sorted(L, key=lambda x: (x % 100, x // 100))

对于数字数据,第三方库(例如NumPy)将支持矢量化操作:

import numpy as np

A = np.array(L)

res = A[np.lexsort((A // 100, A % 100))]

array([101, 301, 401, 202, 303, 104, 204, 105, 305, 306, 407, 408, 409,
       410, 311, 313])