我从一个排序的csv创建了以下列表

list1 = sorted(csv1, key=operator.itemgetter(1))

实际上,我想根据两个标准对列表进行排序:首先是字段1中的值,然后是字段2中的值。我怎么做呢?


是这样的:

import operator
list1 = sorted(csv1, key=operator.itemgetter(1, 2))

list1 = sorted(csv1, key=lambda x: (x[1], x[2]) )

Python有一个稳定的排序,所以如果性能不是问题,最简单的方法是按字段2排序,然后再按字段1排序。

这将给你想要的结果,唯一的问题是,如果它是一个大列表(或者你想经常排序),调用sort两次可能是一个不可接受的开销。

list1 = sorted(csv1, key=operator.itemgetter(2))
list1 = sorted(list1, key=operator.itemgetter(1))

这样做也可以很容易地处理你想要一些列反向排序的情况,只需要在必要时包含'reverse=True'参数。

否则,您可以将多个参数传递给itemgetter或手动构建一个元组。这可能会更快,但有一个问题,如果某些列想要反向排序,它就不能很好地泛化(数值列仍然可以通过对其求反来反向排序,但这会使排序不稳定)。

如果你不需要任何列反向排序,可以给itemgetter多个参数,如果你可以,列不是数值的或者你想保持排序稳定那就进行多个连续排序。

编辑:对于那些理解这是如何回答原始问题的评论者来说,这里有一个例子,它准确地展示了排序的稳定性如何确保我们可以对每个键进行单独的排序,并最终根据多个标准对数据进行排序:

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参数如何保持名字的顺序,而简单地排序然后反转列表将失去第三个排序键的所需顺序。


使用lambda函数时不需要导入任何东西。 下面按第一个元素排序,然后按第二个元素排序。你也可以通过一个字段升序排序,另一个字段降序排序,例如:

sorted_list = sorted(list, key=lambda x: (x[0], -x[1]))

employees.sort(key = lambda x:x[1])
employees.sort(key = lambda x:x[0])

我们也可以用.sort和lambda一起使用2次,因为python的sort是稳定的。这将首先根据第二个元素x[1]对列表进行排序。然后,它将排序第一个元素x[0](最高优先级)。

employees[0] = "Employee's Name"
employees[1] = "Employee's Salary"

这相当于做以下事情:

employees.sort(key = lambda x:(x[0], x[1]))

使用下面的字典排序列表将排序列表降序第一列为工资,第二列为年龄

d=[{'salary':123,'age':23},{'salary':123,'age':25}]
d=sorted(d, key=lambda i: (i['salary'], i['age']),reverse=True)

输出:[{“工资”:123年,“年龄”:25},{“工资”:123年,“年龄”:23}]


按升序可以使用:

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)

python 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]))

在阅读了这篇文章中的答案后,我写了一个通用的解决方案,适用于任意数量的列:

def sort_array(array, *columns):
    for col in columns:
        array.sort(key = lambda x:x[col])

OP会这样称呼它:

sort_array(list1, 2, 1)

先按列2排序,再按列1排序。 (最重要的一栏放在最后)


如果你想对数组进行排序, 根据升序和降序遵循下面提到的方法。为此,你可以使用函数。 让我们考虑下面的例子: 输入:[[1、2],[3 3],(2,1)[1],[4 1],[3,1]] 预期输出:[[4 1],[3,1],[3 3],(2,1)[1],[1、2]] 代码使用:

    arr = [[1,2],[3,3],[2,1],[1,1],[4,1],[3,1]]
    arr.sort(key=lambda ele: (ele[0], -ele[1]), reverse=True)
    # output [[4, 1], [3, 1], [3, 3], [2, 1], [1, 1], [1, 2]]

负号是程序达到预期结果的原因。