我从已排序的csv
创建了以下列表list1 = sorted(csv1, key=operator.itemgetter(1))
我实际上想按两个标准对列表进行排序:首先是字段1中的值,然后是字段2中的值。我该怎么做?
答案 0 :(得分:264)
回复此死线程进行存档。
使用lambda函数时无需导入任何内容
以下内容按第一个元素排序list
,然后按第二个元素排序。
sorted(list, key=lambda x: (x[0], -x[1]))
答案 1 :(得分:141)
import operator
list1 = sorted(csv1, key=operator.itemgetter(1, 2))
答案 2 :(得分:17)
Python具有稳定的排序,因此只要性能不是问题,最简单的方法是按字段2对其进行排序,然后再按字段1对其进行排序。
这将为您提供您想要的结果,唯一的问题是如果它是一个大列表(或者您想要经常排序),那么调用sort两次可能是一个不可接受的开销。
list1 = sorted(csv1, key=operator.itemgetter(2))
list1 = sorted(list1, key=operator.itemgetter(1))
这样做也可以轻松处理您希望某些列反向排序的情况,只需在必要时包含'reverse = True'参数。
否则,您可以将多个参数传递给itemgetter或手动构建元组。这可能会更快,但有一个问题是,如果某些列想要进行反向排序,它们不能很好地推广(数字列仍然可以通过否定它们来反转,但这会使排序保持稳定)。
因此,如果您不需要任何反向排序的列,请为itemgetter添加多个参数(如果可能),并且列不是数字,或者您希望保持sort stable连续多次排序。
编辑:对于在理解如何回答原始问题时遇到问题的评论者,这里有一个示例,它准确地说明了排序的稳定性如何确保我们可以对每个键和最终得出按多个标准排序的数据:
DATA = [
('Jones', 'Jane', 58),
('Smith', 'Anne', 30),
('Jones', 'Fred', 30),
('Smith', 'John', 60),
('Smith', 'Fred', 30),
('Jones', 'Anne', 30),
('Smith', 'Jane', 58),
('Smith', 'Twin2', 3),
('Jones', 'John', 60),
('Smith', 'Twin1', 3),
('Jones', 'Twin1', 3),
('Jones', 'Twin2', 3)
]
# Sort by Surname, Age DESCENDING, Firstname
print("Initial data in random order")
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
First we sort by first name, after this pass all
Twin1 come before Twin2 and Anne comes before Fred''')
DATA.sort(key=lambda row: row[1])
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
Second pass: sort by age in descending order.
Note that after this pass rows are sorted by age but
Twin1/Twin2 and Anne/Fred pairs are still in correct
firstname order.''')
DATA.sort(key=lambda row: row[2], reverse=True)
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
Final pass sorts the Jones from the Smiths.
Within each family members are sorted by age but equal
age members are sorted by first name.
''')
DATA.sort(key=lambda row: row[0])
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
这是一个可运行的示例,但是为了节省运行它的人,输出是:
Initial data in random order
Jones Jane 58
Smith Anne 30
Jones Fred 30
Smith John 60
Smith Fred 30
Jones Anne 30
Smith Jane 58
Smith Twin2 3
Jones John 60
Smith Twin1 3
Jones Twin1 3
Jones Twin2 3
First we sort by first name, after this pass all
Twin1 come before Twin2 and Anne comes before Fred
Smith Anne 30
Jones Anne 30
Jones Fred 30
Smith Fred 30
Jones Jane 58
Smith Jane 58
Smith John 60
Jones John 60
Smith Twin1 3
Jones Twin1 3
Smith Twin2 3
Jones Twin2 3
Second pass: sort by age in descending order.
Note that after this pass rows are sorted by age but
Twin1/Twin2 and Anne/Fred pairs are still in correct
firstname order.
Smith John 60
Jones John 60
Jones Jane 58
Smith Jane 58
Smith Anne 30
Jones Anne 30
Jones Fred 30
Smith Fred 30
Smith Twin1 3
Jones Twin1 3
Smith Twin2 3
Jones Twin2 3
Final pass sorts the Jones from the Smiths.
Within each family members are sorted by age but equal
age members are sorted by first name.
Jones John 60
Jones Jane 58
Jones Anne 30
Jones Fred 30
Jones Twin1 3
Jones Twin2 3
Smith John 60
Smith Jane 58
Smith Anne 30
Smith Fred 30
Smith Twin1 3
Smith Twin2 3
特别注意第二步中reverse=True
参数如何按顺序保存第一个名称,而简单排序然后反转列表将失去第三个排序键的所需顺序。
答案 3 :(得分:5)
def keyfunc(x):
return tuple(x[1],x[2])
list1 = sorted(csv1, key=keyfunc)
答案 4 :(得分:3)
employees.sort(key = lambda x:x[1])
employees.sort(key = lambda x:x[0])
我们还可以将.sort与lambda一起使用2次,因为python sort到位且稳定。这将首先根据第二个元素x [1]对列表进行排序。然后,它将对第一个元素x [0](最高优先级)进行排序。
员工[0] =员工姓名 员工[1] =员工工资
这等效于执行以下操作: employee.sort(key = lambda x:(x [0],x [1]))
答案 5 :(得分:0)
使用下面的字典排序列表将按降序对列表进行排序,第一列为薪水,第二列为年龄
highlight.js
输出:[{'salary':123,'age':25},{'salary':123,'age':23}]
答案 6 :(得分:0)
您可以按升序使用:
sorted_data= sorted(non_sorted_data, key=lambda k: (k[1],k[0]))
或按降序使用:
sorted_data= sorted(non_sorted_data, key=lambda k: (k[1],k[0]),reverse=True)
答案 7 :(得分:0)
蟒蛇 3 https://docs.python.org/3.5/howto/sorting.html#the-old-way-using-the-cmp-parameter
from functools import cmp_to_key
def custom_compare(x, y):
# custom comparsion of x[0], x[1] with y[0], y[1]
return 0
sorted(entries, key=lambda e: (cmp_to_key(custom_compare)(e[0]), e[1]))
答案 8 :(得分:0)
在阅读此线程中的答案后,我编写了一个适用于任意数量列的通用解决方案:
def sort_array(array, *columns):
for col in columns:
array.sort(key = lambda x:x[col])
OP 会这样称呼它:
sort_array(list1, 2, 1)
首先按第 2 列排序,然后按第 1 列排序。
(最重要的列在最后)