Python:如何按照字典键的一部分对项目进行排序?

6

假设我有一个国王的字典,其中以罗马数字作为键,以整数形式表示的罗马数字作为值。

d = {'Zemco III': 3, 'Usamec XL': 40, 'Usamec VII': 7, 'Robert VIII': 8, 'Usamec XLII': 42, 'Mary XXIV': 24, 'Robert III': 3, 'Robert XV': 15, 'Usamec XLIX': 49}

我想将列表按年龄从老到年轻排序,即Usamec XLII应该排在Usamec XLIX之前。我还想按字母顺序对列表进行排序,即Usamec XLII应该排在Zemco III之前。

我的方法是首先按名称排序,然后按罗马数字值排序,如下:

x = sorted(d.items(),key=operator.itemgetter(0))
y = sorted(x,key=operator.itemgetter(1))

然而,由于罗马数字是密钥的一部分,我的字母排序并没有按照预期工作。我的问题是,我是否可以按照密钥的一部分来对字典进行排序,例如如果我的密钥是Zemco III,是否可以使用key.split()[0]而不是整个密钥来对项目进行排序?谢谢!

2个回答

2

key 是一个函数,它接收一个项并返回你需要排序的内容。它可以是任何东西。

这将按照 (去掉最右边单词的名称,数字) 键对项目进行排序:

In [92]: sorted(d.items(), key=lambda (name, num): (name.rsplit(None, 1)[0], num))
Out[92]:
[('Mary XXIV', 24),
 ('Robert III', 3),
 ('Robert VIII', 8),
 ('Robert XV', 15),
 ('Usamec VII', 7),
 ('Usamec XL', 40),
 ('Usamec XLII', 42),
 ('Usamec XLIX', 49),
 ('Zemco III', 3)]

如果您使用Python 3,请使用这个key
lambda item: (item[0].rsplit(None, 1)[0], item[1])

key.rsplit(None, 1)[0]在多词名字的情况下比key.split()[0]更好。


作为一个后续问题,如果我的字典被排序,数字先出现,然后是名称,并且我再次想按名称的第一部分排序怎么办?遵循相同的格式,我会得到:sorted(d.items(), key=lambda (num,name): (num,name.rsplit(None, 1)[0])) 但是怎样加入类似 key=operator.itemgetter(1) 的内容呢?谢谢。 - user2821275
如果您按相同的键进行排序,那么元组应该是相同的:(name.rsplit(None, 1)[0], num)。只有 lambda 参数的顺序会改变。如果您仍然需要拆分名称,则 itemgetter 没有帮助。您的反转字典如何处理重复的数字? - Pavel Anossov

0

如果你只是想把它排序,你可以这样做:

sorted_stuff = sorted([(ord(x[0]), x, y) for x, y in d.items()])
final_sorted = [(y,z) for x,y,z in sorted_stuff]

sorted_stuff 的样子会是这样的:

[(77, 'Mary XXIV', 24), (82, 'Robert III', 3)]

final_sorted 将被正确格式化:

[('Mary XXIV', 24), ('Robert III', 3)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接