如何按列表中特定位置的值对字典进行排序?
How to sort a dict by a specific location in the list in its value?
我有一本看起来像这样的字典:
d1= {'a':[1, 5], 'b':[2, 23], 'c':[99,12]}
在字典有两个值的列表之前,我可以这样排序:
for key in sorted(mydict, key=mydict.get, reverse=True):
print key.rstrip() + " : " + str(mydict[key])
这实际上仍然适用于列表中的 第一个 值,但它对第二个值没有任何作用:
c : [99, 12]
b : [2, 23]
a : [1, 5]
如何改为按列表中的第二个值排序?如果我这样选择,如何按第二个值然后第一个值排序,反之亦然?
实际上它对第二个值做了一些事情:这个用作 tie-breaker 以防第一个值相等。
尽管如此,您可以简单地使用 lambda
表达式作为 key
:
for key in sorted(mydict, key=lambda x: (mydict.get(x)[1],mydict.get(x)[0]), reverse=True):
print key.rstrip() + " : " + str(mydict[key])
这里发生的事情是你把如何排序的值当作"key",你通过调用mydict.get(x)
获得值,现在你可以构造一个新的元组(mydict.get(x)[1],mydict.get(x)[0])
,其中第二个元素放在第一位,第一个元素放在第二个。
由于元组按字典顺序排序,这意味着Python 将首先比较第一个元素,如果相等则比较第二个元素。现在因为我们交换了位置,所以它会先比较第二个,然后再比较第一个。
然而,正如@Jean-FrançoisFabre 所说,您可以使用 [::-1]
来 反转 保存 .get
操作的元组(以及结果看起来更优雅)所以:
for key in sorted(mydict, key=lambda x: mydict.get(x)[::-1], reverse=True):
print key.rstrip() + " : " + str(mydict[key])
但是请注意,解决此问题的更优雅的方法是立即对 key-value 元组进行排序:
for key,value in sorted(mydict.items(), key=lambda x:x[1][::-1], reverse=True):
print key.rstrip() + " : " + str(value)
所以这个问题很老了,但这可能对某些人有所帮助。免责声明:我不知道 python 所以我将用非常广泛的术语来描述它,这可能是可能的,也可能不是。我在 C# 中完成了此操作。
如果您需要对项目进行一次排序,请使用 Willern 的完美答案。如果您需要一直对它们进行排序,请继续阅读。
我发现创建一个将字典和列表混合在一起的新集合对象最方便。新的集合对象导出了列表将拥有的所有方法,并通过向两个集合添加内容来处理添加等。构造函数采用 lambda 从值中获取键,以便可以填充字典。该集合还导出了字典用于读取的所有方法(但出于显而易见的原因不用于写入),因此键查找速度很快。此外,还有一个 AddRange 方法,这样插入就不会是 O(N^2)。 AddRange 只会将所有项目追加到列表中并调用排序。
如何按内容排序的扩展应该非常明显。
我有一本看起来像这样的字典:
d1= {'a':[1, 5], 'b':[2, 23], 'c':[99,12]}
在字典有两个值的列表之前,我可以这样排序:
for key in sorted(mydict, key=mydict.get, reverse=True):
print key.rstrip() + " : " + str(mydict[key])
这实际上仍然适用于列表中的 第一个 值,但它对第二个值没有任何作用:
c : [99, 12]
b : [2, 23]
a : [1, 5]
如何改为按列表中的第二个值排序?如果我这样选择,如何按第二个值然后第一个值排序,反之亦然?
实际上它对第二个值做了一些事情:这个用作 tie-breaker 以防第一个值相等。
尽管如此,您可以简单地使用 lambda
表达式作为 key
:
for key in sorted(mydict, key=lambda x: (mydict.get(x)[1],mydict.get(x)[0]), reverse=True): print key.rstrip() + " : " + str(mydict[key])
这里发生的事情是你把如何排序的值当作"key",你通过调用mydict.get(x)
获得值,现在你可以构造一个新的元组(mydict.get(x)[1],mydict.get(x)[0])
,其中第二个元素放在第一位,第一个元素放在第二个。
由于元组按字典顺序排序,这意味着Python 将首先比较第一个元素,如果相等则比较第二个元素。现在因为我们交换了位置,所以它会先比较第二个,然后再比较第一个。
然而,正如@Jean-FrançoisFabre 所说,您可以使用 [::-1]
来 反转 保存 .get
操作的元组(以及结果看起来更优雅)所以:
for key in sorted(mydict, key=lambda x: mydict.get(x)[::-1], reverse=True): print key.rstrip() + " : " + str(mydict[key])
但是请注意,解决此问题的更优雅的方法是立即对 key-value 元组进行排序:
for key,value in sorted(mydict.items(), key=lambda x:x[1][::-1], reverse=True): print key.rstrip() + " : " + str(value)
所以这个问题很老了,但这可能对某些人有所帮助。免责声明:我不知道 python 所以我将用非常广泛的术语来描述它,这可能是可能的,也可能不是。我在 C# 中完成了此操作。
如果您需要对项目进行一次排序,请使用 Willern 的完美答案。如果您需要一直对它们进行排序,请继续阅读。
我发现创建一个将字典和列表混合在一起的新集合对象最方便。新的集合对象导出了列表将拥有的所有方法,并通过向两个集合添加内容来处理添加等。构造函数采用 lambda 从值中获取键,以便可以填充字典。该集合还导出了字典用于读取的所有方法(但出于显而易见的原因不用于写入),因此键查找速度很快。此外,还有一个 AddRange 方法,这样插入就不会是 O(N^2)。 AddRange 只会将所有项目追加到列表中并调用排序。
如何按内容排序的扩展应该非常明显。