按两个字段对 Python 列表进行排序[重复]

2024-12-20 08:38:00
admin
原创
165
摘要:问题描述:我有以下根据排序的 csv 创建的列表list1 = sorted(csv1, key=operator.itemgetter(1)) 我实际上想按两个标准对列表进行排序:首先按字段 1 中的值,然后按字段 2 中的值。我该怎么做?解决方案 1:使用 lambda 函数时无需导入任何内容。 以下l...

问题描述:

我有以下根据排序的 csv 创建的列表

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

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


解决方案 1:

使用 lambda 函数时无需导入任何内容。

以下list按第一个元素排序,然后按第二个元素排序。您还可以按一个字段升序排序,按另一个字段降序排序,例如:

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

解决方案 2:

像这样:

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

解决方案 3:

Python 具有稳定的排序,因此只要性能不是问题,最简单的方法就是按字段 2 排序,然后再次按字段 1 排序。

这将为您提供想要的结果,唯一的问题是,如果它是一个大列表(或者您想经常对其进行排序)则两次调用排序可能是不可接受的开销。

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

解决方案 4:

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

解决方案 5:

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

解决方案 6:

使用下面的方法对字典列表进行排序,将按第一列的薪水和第二列的年龄的降序排列列表

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

输出:[{'salary': 123, 'age': 25}, {'salary': 123, 'age': 23}]

解决方案 7:

如果您想根据升序和降序对数组进行排序,请按照下面提到的方法进行操作。为此,您可以使用 lambda 函数。

让我们考虑下面的例子,

输入:[[1,2],[3,3],[2,1],[1,1],[4,1],[3,1]]

预期输出:[[4, 1], [3, 1], [3, 3], [2, 1], [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]]

负号是程序产生预期结果的原因。

解决方案 8:

按升序排列,您可以使用:

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)

解决方案 9:

阅读完该主题中的答案后,我编写了一个适用于任意数量列的通用解决方案:

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

OP 会这样称呼它:

sort_array(list1, 2, 1)

首先按第 2 列排序,然后按第 1 列排序。

(最重要的列排在最后)

解决方案 10:

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]))
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2500  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1541  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   16  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   23  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   26  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用