如何按值对字典进行排序?
我有一个从数据库中的两个字段读取的值字典:字符串字段和数字字段.字符串字段是唯一的,因此这是字典的键.
我可以对键进行排序,但是如何根据值进行排序?
注意:我已阅读Stack Overflow问题如何按Python中字典的值对字典列表进行排序?并且可能可以更改我的代码以获得字典列表,但由于我不需要字典列表,我想知道是否有更简单的解决方案.
回答
不可能对字典进行排序,只能获得已排序字典的表示.字典本质上是无序的,但其他类型(如列表和元组)则不是.所以你需要一个有序的数据类型来表示排序的值,这将是一个列表 - 可能是一个元组列表.
例如,
import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))
sorted_x
将是由每个元组中的第二个元素排序的元组列表.dict(sorted_x) == x
.
对于那些希望对键而不是值进行排序的人:
import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))
在Python3中,因为不允许解包[1]我们可以使用
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda kv: kv[1])
- saidimu:因为我们已经使用`sorted()`,所以传递`reverse = True`参数会更有效率.
- `sorted_x.reverse()`会给你一个降序(由第二个元组元素)
- 在python3中我使用了lambda:`sorted(d.items(),key = lambda x:x [1])`.这会在python 2.x中工作吗?
- OrderedDict在2.7中添加到集合中.排序示例如下所示:http://docs.python.org/library/collections.html?highlight = ordddddordordor-examples-and-recipes
- 按价值计划排序各种字典:http://writeonly.wordpress.com/2008/08/30/sorting-dictionaries-by-value-in-python-improved/
- 这个答案已经过时了.字典在Python 3.7中排序.
- `sorted_x = sorted(x.items(),key = operator.itemgetter(1),reverse = True)`看起来好于先按升序排序然后翻转列表.
- ......从Python 3.6开始,"PEP 468"保留了函数中**kwargs的顺序"现在已经实现了!基于INADA Naoki对"紧凑型字典"的实现,这将有助于以下情况:然后我可以通过dict上的迭代以相同的顺序检索(使用_built-in_ dict 🙂 ...)
- @Keyo是的; 3.x没有`iteritems()`方法了.但是,您仍然可以使用操作员模块(如果需要).
- @洛根:你在说什么?x是一本字典,问题是要根据其值对一个字典进行排序。
- @Dejel不,在Python 3.x`sorted(d.items(),key = ...)`将返回一个`(key,value)`元组的列表.
- 我不确定我喜欢编辑(这是我的答案!).要对键进行排序,我通常会排序(x.items()).除非dict具有无法比较的值,否则这种方法有效.
很简单: sorted(dict1, key=dict1.get)
嗯,实际上可以进行"按字典值排序".最近我必须在Code Golf(Stack Overflow问题代码高尔夫:Word频率图表)中这样做.最简单的问题是这样的:给定一个文本,计算每个单词遇到的频率,并显示顶部单词列表,按频率降低排序.
如果构造一个字典,其中单词为键,每个单词的出现次数为值,则简化为:
from collections import defaultdict
d = defaultdict(int)
for w in text.split():
d[w] += 1
然后你可以得到一个单词列表,按照使用频率sorted(d, key=d.get)
排序 - 排序迭代字典键,使用单词出现次数作为排序键.
for w in sorted(d, key=d.get, reverse=True):
print w, d[w]
我正在写这个详细的解释,以说明人们通常所说的"我可以轻松地按键排序字典,但我如何按价值排序" - 我认为OP试图解决这个问题.解决方案是根据值做一些键列表,如上所示.
- 这也很好,但*`key = operator.itemgetter(1)`*应该比*`key = d.get`*更具可扩展性
- @bli`sorted_keys = sorted(d.items(),key = itemgetter(1),reverse = True)`和`for key,val in sorted_keys:print"%s:%d"%(key,val)` - itemgetter在调用时创建一个函数,你不像在你的例子中那样直接使用它.并且dict上的普通迭代使用没有值的键
- 我来自未来告诉你`collections.Counter`,它有一个你可能感兴趣的`most_common`方法:)
- 您首先需要:import collections#以使用defaultdict
- @raylu我确实使用itemgetter观察到"不工作"的行为:-----`来自operator import itemgetter d = {"a":7,"b":1,"c":5,"d": 3:sorted_keys =已排序(d,key = itemgetter,reverse = True),用于sorted_keys中的键:print"%s:%d"%(key,d [key])`----- - > b:1 c :5 a:7 d:3每次运行代码时结果都会改变:很奇怪.(抱歉,无法正常显示代码)
- @Eevee-在非f2f简短评论中有被误解的风险。有趣的花絮:`collections.Counter`在2.7中被添加,它几乎是7年前发布的!(那时我还不知道它-再加上为了简洁起见,我会在代码高尔夫球中避免使用它,这是游戏唯一的困扰)
你可以使用:
reverse=True
这将根据字典中从最小到最大的每个条目的值对字典进行排序.
- 我个人更喜欢`key = lambda(k,v):v`
- @Claudiu我也喜欢那种`(k,v)`语法,但它在Python 3中不可用,其中[tuple parameter unpacking](https://www.python.org/dev/peps/pep-3113/)被删除了.
- ```dict(sorted(d.items(), key=lambda x: x[1]))``` .
Dicts无法排序,但您可以从中构建排序列表.
dict值的排序列表:
sorted(d.values())
按键排序的(键,值)对列表:
from operator import itemgetter
sorted(d.items(), key=itemgetter(1))
- Dicts can now be sorted, starting with CPython 3.6 and all other Python implementations starting with 3.7
在最近的Python 2.7中,我们有了新的OrderedDict类型,它记住了项目的添加顺序.
>>> d = {"third": 3, "first": 1, "fourth": 4, "second": 2}
>>> for k, v in d.items():
... print "%s: %s" % (k, v)
...
second: 2
fourth: 4
third: 3
first: 1
>>> d
{'second': 2, 'fourth': 4, 'third': 3, 'first': 1}
要从原始字典创建新的有序字典,请按值排序:
>>> from collections import OrderedDict
>>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1]))
OrderedDict的行为类似于普通的dict:
>>> for k, v in d_sorted_by_value.items():
... print "%s: %s" % (k, v)
...
first: 1
second: 2
third: 3
fourth: 4
>>> d_sorted_by_value
OrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])
- @Nas Banov:它不是按键排序.它按顺序排序,我们创建项目.在我们的例子中,我们按值排序.不幸的是,不幸的是,选择了3项dict,因此顺序是相同的,当按值和键排序时,所以我扩展了样本字典.
- 这不是问题所在 - 它不是关于维护键的顺序而是关于"按值排序"
- Note: As of 3.6 (as a CPython/PyPy implementation detail) and as of 3.7 (as a Python language guarantee), plain `dict` is insertion ordered as well, so you can just replace `OrderedDict` with `dict` for code running on modern Python. `OrderedDict` isn't really needed anymore unless you need to rearrange the order of an existing `dict` (with `move_to_end`/`popitem`) or need equality comparisons to be order-sensitive. It uses a lot more memory than plain `dict`, so if you can, `dict` is the way to go.
更新:2015年12月5日使用Python 3.5
虽然我发现接受的答案很有用,但我也感到惊讶的是它没有更新为从标准库集合模块引用OrderedDict作为一种可行的,现代的替代方案 - 旨在解决这类问题.
from operator import itemgetter
from collections import OrderedDict
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))
# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])
官方的OrderedDict文档也提供了一个非常类似的例子,但是使用lambda作为sort函数:
# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
与Hank Gay的回答几乎相同;
sorted([(value,key) for (key,value) in mydict.items()])
或者根据John Fouhy的建议进行优化;
sorted((value,key) for (key,value) in mydict.items())
- ..和Hank Gay的答案一样,你不需要方括号.sorted()将很乐意接受任何迭代,例如生成器表达式.
使用namedtuple通常非常方便.例如,您有一个'name'字典作为键,'score'作为值,您想要对'score'进行排序:
import collections
Player = collections.namedtuple('Player', 'score name')
d = {'John':5, 'Alex':10, 'Richard': 7}
首先排序得分最低:
worst = sorted(Player(v,k) for (k,v) in d.items())
首先排序得分最高:
best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True)
现在你可以得到名字和得分,让我们说第二好的球员(指数= 1)非常像这样:
player = best[1]
player.name
'Richard'
player.score
7
从Python 3.6开始,内置的dict将被订购
好消息,所以OP的原始用例是从数据库中检索到的映射对,其中唯一的字符串id作为键,数值作为值进入内置的Python v3.6 + dict,现在应该遵循插入顺序.
如果从数据库查询中得出结果的两个列表表达式,如:
SELECT a_key, a_value FROM a_table ORDER BY a_value;
将存储在两个Python元组中,k_seq和v_seq(由数字索引对齐,当然长度相同),然后:
k_seq = ('foo', 'bar', 'baz')
v_seq = (0, 1, 42)
ordered_map = dict(zip(k_seq, v_seq))
允许稍后输出为:
for k, v in ordered_map.items():
print(k, v)
在这种情况下产生(对于新的Python 3.6+内置字典!):
foo 0
bar 1
baz 42
每个v的相同排序.
在我的机器上安装Python 3.5的地方,它目前产生:
bar 1
foo 0
baz 42
细节:
正如Raymond Hettinger在2012年提出的那样(参见python-dev上的邮件主题为"更快速迭代的更紧凑词典"),现在(2016年)由Victor Stinner发送给python-dev,主题为"Python 3.6 dict"紧凑并获得私有版本;关键字变得有序"由于问题27350的修复/实现"紧凑和有序的dict"在Python 3.6中我们现在可以使用内置的dict来维护插入顺序!!
希望这将导致薄层OrderedDict实现作为第一步.正如@ JimFasarakis-Hilliard所指出的那样,有些人在未来也会看到OrderedDict类型的用例.我认为Python社区将仔细检查,如果这将经得起时间的考验,以及接下来的步骤将是什么.
是时候重新考虑我们的编码习惯,不要错过稳定订购的可能性:
- 关键字参数和
- (中间)dict存储
第一个是因为它在某些情况下简化了函数和方法实现中的调度.
第二,因为它鼓励更容易使用dict
s作为处理管道的中间存储.
Raymond Hettinger 在他的旧金山Python Meetup Group演讲2016-DEC-08上提供了解释" Python 3.6 Dictionaries背后的技术 " 的文档.
也许相当一些Stack Overflow高度装饰的问答页面将收到此信息的变体,许多高质量的答案也需要每个版本更新.
警告Empat(但也见下面更新2017-12-15):
正如@ajcr正确地指出:"这个新实现的顺序保留方面被认为是一个实现细节,不应该依赖它." (来自whatsnew36)没有采摘,但引用被削减了一点悲观;-).它继续作为"(这可能在未来发生变化,但是在更改语言规范之前,希望在几种版本的语言中使用这个新的dict实现,以便为所有当前和未来的Python实现强制保持语义保持语义;这也是有助于保持与随机迭代顺序仍然有效的语言的旧版本的向后兼容性,例如Python 3.5)."
因此,在一些人的语言(如德国),使用形状的语言,意志,现在已被宣布......在whatsnew36.
更新2017-12-15:
在给python-dev列表的邮件中,Guido van Rossum声明:
因此,dict插入排序的版本3.6 CPython副作用现在成为语言规范的一部分(而不再仅仅是实现细节).collections.OrderedDict
在讨论期间,Raymond Hettinger提醒,该邮件线程也浮现了一些与众不同的设计目标.
- 应强调您链接到的"whatsnew"页面上的警告:**此新实施的订单保留方面被视为实施细节,不应依赖**.没有人应该假设`dict`类型将尊重其代码中的插入顺序.这不是语言定义的一部分,实现可能会在以后的任何版本中发生变化.继续使用`OrderedDict`来保证订单.
- @AlexRiley这个警告不再准确.Python3.7保证有序字典.
我遇到了同样的问题,我解决了这个问题:
WantedOutput = sorted(MyDict, key=lambda x : MyDict[x])
(回答"不可能对词典进行排序"的人没有读到这个问题!事实上,"我可以对键进行排序,但是如何根据值进行排序?"显然意味着他想要一个列表密钥根据其值的值排序.)
请注意,订单没有很好地定义(具有相同值的键将在输出列表中以任意顺序排列).
在Python 2.7中,只需:
from collections import OrderedDict
# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
# dictionary sorted by key
OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
复制粘贴来自:http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes
请享用 😉
如果值是数字,您还可以使用集合中的计数器
from collections import Counter
x = {'hello': 1, 'python': 5, 'world': 3}
c = Counter(x)
print(c.most_common())
>> [('python', 5), ('world', 3), ('hello', 1)]
这是代码:
import operator
origin_list = [
{"name": "foo", "rank": 0, "rofl": 20000},
{"name": "Silly", "rank": 15, "rofl": 1000},
{"name": "Baa", "rank": 300, "rofl": 20},
{"name": "Zoo", "rank": 10, "rofl": 200},
{"name": "Penguin", "rank": -1, "rofl": 10000}
]
print ">> Original >>"
for foo in origin_list:
print foo
print "n>> Rofl sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rofl")):
print foo
print "n>> Rank sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rank")):
print foo
结果如下:
原版的
{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
ROFL
{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}
秩
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
尝试以下方法.让我们用以下数据定义一个名为mydict的字典:
mydict = {'carl':40,
'alan':2,
'bob':1,
'danny':3}
如果想要按键对字典进行排序,可以执行以下操作:
for key in sorted(mydict.iterkeys()):
print "%s: %s" % (key, mydict[key])
这应该返回以下输出:
alan: 2
bob: 1
carl: 40
danny: 3
另一方面,如果想要按值对字典进行排序(如问题中所述),可以执行以下操作:
for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)):
print "%s: %s" % (key, value)
此命令的结果(按值对字典排序)应返回以下内容:
bob: 1
alan: 2
danny: 3
carl: 40
您也可以创建"倒排索引"
from collections import defaultdict
inverse= defaultdict( list )
for k, v in originalDict.items():
inverse[v].append( k )
现在您的逆值具有值; 每个值都有一个适用键列表.
for k in sorted(inverse):
print k, inverse[k]
您可以使用collections.Counter.请注意,这适用于数字和非数字值.
>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> from collections import Counter
>>> #To sort in reverse order
>>> Counter(x).most_common()
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> Counter(x).most_common()[::-1]
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
>>> #To get a dictionary sorted by values
>>> from collections import OrderedDict
>>> OrderedDict(Counter(x).most_common()[::-1])
OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])
- 这与[Ivan Sas的回答](http://stackoverflow.com/questions/613183/python-sort-a-dictionary-by-value/11230132#11230132)有什么不同?
从Python 3.6开始,dict
对象现在按插入顺序排序.它正式符合Python 3.7的规范.
>>> words = {"python": 2, "blah": 4, "alice": 3}
>>> dict(sorted(words.items(), key=lambda x: x[1]))
{'python': 2, 'alice': 3, 'blah': 4}
在此之前,你必须使用OrderedDict
.
Python 3.7文档说:
您可以使用skip dict,它是一个按值永久排序的字典.
>>> data = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> SkipDict(data)
{0: 0.0, 2: 1.0, 1: 2.0, 4: 3.0, 3: 4.0}
如果您使用keys()
,values()
或者items()
您将按值按顺序迭代.
它是使用跳过列表数据结构实现的.
from django.utils.datastructures import SortedDict
def sortedDictByKey(self,data):
"""Sorted dictionary order by key"""
sortedDict = SortedDict()
if data:
if isinstance(data, dict):
sortedKey = sorted(data.keys())
for k in sortedKey:
sortedDict[k] = data[k]
return sortedDict
- 问题是:按价值排序,而不是按键...我喜欢看功能.您可以导入集合,当然也可以使用sorted(data.values())
您还可以使用可以传递给键的自定义函数.
def dict_val(x):
return x[1]
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=dict_val)
def dict_val(x):
return x[1]
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=dict_val)
还有一种方法是使用labmda函数
这是一个使用zip d.values()
和d.keys()
的解决方案.此链接的几行(在Dictionary视图对象上)是:
所以我们可以做到以下几点:
d = {'key1': 874.7, 'key2': 5, 'key3': 8.1}
d_sorted = sorted(zip(d.values(), d.keys()))
print d_sorted
# prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]
正如Dilettant所指出的,Python 3.6现在将保持订单!我以为我会共享一个我编写的函数,它可以简化迭代(元组,列表,字典)的排序.在后一种情况下,您可以对键或值进行排序,并且可以将数值比较考虑在内.仅适用于> = 3.6!
当您尝试在包含例如字符串和整数的迭代上使用sorted时,sorted()将失败.当然你可以用str()强制进行字符串比较.但是,在某些情况下,您希望进行实际数值比较,其中12
小于20
(在字符串比较中不是这种情况).所以我想出了以下内容.当您想要显式数字比较时,可以使用标志num_as_num
,该标志将尝试将所有值转换为浮点数,从而尝试进行显式数字排序.如果成功,它将进行数字排序,否则它将采用字符串比较.
欢迎提出改进或推送请求的评论.
def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
def _sort(i):
# sort by 0 = keys, 1 values, None for lists and tuples
try:
if num_as_num:
if i is None:
_sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
else:
_sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
else:
raise TypeError
except (TypeError, ValueError):
if i is None:
_sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
else:
_sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))
return _sorted
if isinstance(iterable, list):
sorted_list = _sort(None)
return sorted_list
elif isinstance(iterable, tuple):
sorted_list = tuple(_sort(None))
return sorted_list
elif isinstance(iterable, dict):
if sort_on == 'keys':
sorted_dict = _sort(0)
return sorted_dict
elif sort_on == 'values':
sorted_dict = _sort(1)
return sorted_dict
elif sort_on is not None:
raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
else:
raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, tuple, or dict")
当然,请记住,您需要使用,OrderedDict
因为常规Python词典不保留原始顺序.
from collections import OrderedDict
a = OrderedDict(sorted(originalDict.items(), key=lambda x: x[1]))
from collections import OrderedDict
a = OrderedDict(sorted(originalDict.items(), key=lambda x: x[1]))
如果您没有Pytho
def gen(originalDict):
for x, y in sorted(zip(originalDict.keys(), originalDict.values()), key=lambda z: z[1]):
yield (x, y)
#Yields as a tuple with (key, value). You can iterate with conditional clauses to get what you want.
for bleh, meh in gen(myDict):
if bleh == "foo":
print(myDict[bleh])
n 2.7或更高版本,那么您可以做的最好是迭代生成器函数中的值.(目前是2.4和2.6的OrderedDict 这里,但
def gen(originalDict):
for x, y in sorted(zip(originalDict.keys(), originalDict.values()), key=lambda z: z[1]):
yield (x, y)
#Yields as a tuple with (key, value). You can iterate with conditional clauses to get what you want.
for bleh, meh in gen(myDict):
if bleh == "foo":
print(myDict[bleh])
和
for bleh, meh in gen(myDict):
print(bleh, meh)
您还可以打印出每个值
如果不使用Python 3.0或更高版本,请记得在打印后删除括号
使用ValueSortedDict从http://stardict.sourceforge.net/Dictionaries.php下载:
from dicts.sorteddict import ValueSortedDict
d = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_dict = ValueSortedDict(d)
print sorted_dict.items()
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
迭代一个字典并按其值按降序排序:
$ python --version
Python 3.2.2
$ cat sort_dict_by_val_desc.py
dictionary = dict(siis = 1, sana = 2, joka = 3, tuli = 4, aina = 5)
for word in sorted(dictionary, key=dictionary.get, reverse=True):
print(word, dictionary[word])
$ python sort_dict_by_val_desc.py
aina 5
tuli 4
joka 3
sana 2
siis 1
如果您的值是整数,并且您使用的是Python 2.7或更高版本,则可以使用collections.Counter
而不是dict
.该most_common
方法将为您提供所有项目,按值排序.
months = {"January": 31, "February": 28, "March": 31, "April": 30, "May": 31,
"June": 30, "July": 31, "August": 31, "September": 30, "October": 31,
"November": 30, "December": 31}
def mykey(t):
""" Customize your sorting logic using this function. The parameter to
this function is a tuple. Comment/uncomment the return statements to test
different logics.
"""
return t[1] # sort by number of days in the month
#return t[1], t[0] # sort by number of days, then by month name
#return len(t[0]) # sort by length of month name
#return t[0][-1] # sort by last character of month name
# Since a dictionary can't be sorted by value, what you can do is to convert
# it into a list of tuples with tuple length 2.
# You can then do custom sorts by passing your own function to sorted().
months_as_list = sorted(months.items(), key=mykey, reverse=False)
for month in months_as_list:
print month
刚刚从Python for Everyone中学习了相关技能。
您可以使用一个临时列表来帮助您对字典进行排序:
#Assume dictionary to be:
d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}
# create a temporary list
tmp = []
# iterate through the dictionary and append each tuple into the temporary list
for key, value in d.items():
tmptuple = (value, key)
tmp.append(tmptuple)
# sort the list in ascending order
tmp = sorted(tmp)
print (tmp)
如果要按降序对列表进行排序,只需将原始排序行更改为:
tmp = sorted(tmp, reverse=True)
使用列表推导,一个衬里将是:
#Assuming the dictionary looks like
d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}
#One liner for sorting in ascending order
print (sorted([(v, k) for k, v in d.items()]))
#One liner for sorting in descending order
print (sorted([(v, k) for k, v in d.items()], reverse=True))
样本输出:
#Asending order
[(1.0, 'orange'), (500.1, 'apple'), (789.0, 'pineapple'), (1500.2, 'banana')]
#Descending order
[(1500.2, 'banana'), (789.0, 'pineapple'), (500.1, 'apple'), (1.0, 'orange')]
这适用于3.1.x:
import operator
slovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True)
print(slovar_sorted)
为了完整起见,我使用heapq发布解决方案.请注意,此方法适用于数字和非数字值
>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> x_items = x.items()
>>> heapq.heapify(x_items)
>>> #To sort in reverse order
>>> heapq.nlargest(len(x_items),x_items, operator.itemgetter(1))
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> heapq.nsmallest(len(x_items),x_items, operator.itemgetter(1))
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
由于需要保持与旧版本Python的向后兼容性,我认为OrderedDict解决方案非常不明智。您需要适用于Python 2.7和更早版本的工具。
但是,另一个答案中提到的集合解决方案绝对是极好的,因为您可以重新训练键和值之间的联系,这对于字典而言极为重要。
我不同意另一个答案中提出的第一选择,因为它会丢掉钥匙。
我使用了上面提到的解决方案(如下所示的代码),并保留了对键和值的访问,在我的情况下,排序是在值上进行的,但重要的是在对值进行排序之后对键进行排序。
from collections import Counter
x = {'hello':1, 'python':5, 'world':3}
c=Counter(x)
print c.most_common()
>> [('python', 5), ('world', 3), ('hello', 1)]