Python排序多个属性

Python排序多个属性,python,sorting,dictionary,sorted,Python,Sorting,Dictionary,Sorted,我有一本如下的字典。键值对或用户名:name d = {"user2":"Tom Cruise", "user1": "Tom Cruise"} 我的问题是,我需要按名称对它们进行排序,但是如果多个用户包含如上所述的相同名称,那么我需要按用户名对它们进行排序。我查找了排序函数,但我不太了解cmp参数和lambda。如果有人能解释这些,并帮助我这将是伟大的!谢谢:)cmp已过时lambda只生成一个函数 sorted(d.iteritems(), key=operator.itemgetter(

我有一本如下的字典。键值对或用户名:name

d = {"user2":"Tom Cruise", "user1": "Tom Cruise"}

我的问题是,我需要按名称对它们进行排序,但是如果多个用户包含如上所述的相同名称,那么我需要按用户名对它们进行排序。我查找了排序函数,但我不太了解cmp参数和lambda。如果有人能解释这些,并帮助我这将是伟大的!谢谢:)

cmp
已过时<代码>lambda只生成一个函数

sorted(d.iteritems(), key=operator.itemgetter(1, 0))

我将详细阐述伊格纳西奥·巴斯克斯·艾布拉姆斯的回答<不推荐使用代码>cmp。不要用它。改为使用
属性

lambda
生成一个函数。它是一个表达式,所以可以放在普通
def
语句不能放的地方,但它的主体仅限于一个表达式

my_func = lambda x: x + 1
这定义了一个函数,该函数接受单个参数
x
,并返回
x+1
lambda x,y=1:x+y
定义一个函数,该函数接受一个
x
参数,一个可选的
y
参数,默认值为1,并返回
x+y
。正如您所看到的,它实际上就像一个
def
语句,只是它是一个表达式,并且仅限于身体的一个表达式

属性的目的是
排序
将为要排序的序列的每个元素调用它,并使用它返回的值进行比较

list_ = ['a', 'b', 'c']
sorted(list_, key=lambda x: 1)
请阅读下面的假设示例。在写这篇文章之前,我并没有仔细研究这个问题。尽管如此,它仍然具有教育意义,所以我将不再讨论它。 我们不能再多说了,因为

  • 您不能排序
    dict
    s。您有
    dicts
    s的列表吗?我们可以解决这个问题
  • 您没有显示
    用户名
  • 我想大概是这样的

    users = [{'name': 'Tom Cruise', 'username': user234234234, 'reputation': 1},
             {'name': 'Aaron Sterling', 'username': 'aaronasterling', 'reputation': 11725}]
    
    如果你想确认我比汤姆·克鲁斯更厉害,你可以:

    sorted(users, key=lambda x: x['reputation'])
    
    这只是传递一个函数,该函数返回列表中每个字典的
    “声誉”
    值。但是
    lambdas
    可能会慢一些。大多数情况下,
    运算符。itemgetter
    就是您想要的

    operator.itemgetter
    接受一系列键并返回一个函数,该函数接受一个对象并返回其参数值的元组

    因此
    f=operator.itemgetter('name','username')
    返回的函数与
    lambda d:(d['name',d['username'])
    不同之处在于,原则上,它应该运行得更快,而且您不必查看难看的
    lambda
    表达式

    因此,要按名称和用户名对
    dict
    s列表进行排序,只需执行以下操作

    sorted(list_of_dicts, operator.itemgetter('name', 'username'))
    

    这正是伊格纳西奥·巴斯克斯·艾布拉姆斯所建议的。

    你应该知道dict是无法分类的。但是Python2.7和3.1有这个类collections.OrderedDict

    所以


    在我看来,键是用户名,值是真名。@Ignacio-对。我不知何故错过了您的解决方案中的
    iteritems
    。OP将dict指定为“键值对或用户名:name”,尽管这可能已在中编辑。“一开始我错过了。”乔什·斯梅顿,对。我错过了。我想
    把我甩了。不过我还是不说了,因为它对
    lambda
    itemgetter
    key
    的解释比Ignacio的答案更深入。当然,我只是最近才了解itemgetter,不知道它可以进行键查找和定位+1问题是,这是我的类作业的一部分,我不允许像operator这样导入库。它唯一的内置功能。我明白你的意思,我试着即兴创作。我用了“sorted(l,key=lambda l:(l[0],l[1])”,你认为这和你说的等价吗?不完全一样
    lambda x:(x[1],x[0])
    因此此函数对名称进行排序,但如果名称相同,则对用户名进行排序,还是将其保留在相同的位置?因为我需要它,所以如果名称相同,它会按用户名排序。非常感谢!它按键对它们进行排序。关键是一个元组,元组按元素排序。比较元素0,但如果它们相同,则比较元素1,依此类推。假设列表[(3,2),(1,2),(1,1)]中有元组,并且希望按每个元组中的第二个值对它们进行排序,如果第二个值相同,则按第一个值排序。我所期望的答案是[(1,1),(1,2),(3,2)]。这就是代码所做的吗?是的,事实上,如果它是一个dict,这并不重要,我所需要的是,如果我说的是人的名字和用户名,我需要对这些名字进行排序,但是如果两个或更多的人有相同的名字,那么问题就出现了,在这种情况下,我需要按用户名对这些人进行排序(只有那些人)。
    >>> from collections import OrderedDict
    >>> d=OrderedDict({'D':'X','B':'Z','C':'X','A':'Y'})
    >>> d
    OrderedDict([('A', 'Y'), ('C', 'X'), ('B', 'Z'), ('D', 'X')])
    >>> OrderedDict(sorted((d.items()), key=lambda t:(t[1],t[0])))
    OrderedDict([('C', 'X'), ('D', 'X'), ('A', 'Y'), ('B', 'Z')])