python3.6字典有序_Python如何按值对字典进行排序?

我有一个从数据库中的两个字段中读取值的字典:一个字符串字段和一个数字字段。字符串字段是唯一的,所以这是字典的关键。

我可以对键进行排序,但是如何根据这些值进行排序?

注意:我已阅读Stack Overflow问题

答案

无法对字典进行排序,只能得到已排序的字典的表示形式。字典本质上是无序的,但其他类型,如列表和元组,不是。所以你需要一个有序的数据类型来表示排序的值,这将是一个列表 – 可能是一个元组列表。

例如,

importoperator

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。

对于那些希望按键而不是数值进行排序的人:

importoperator

x= {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}sorted_x=sorted(x.items(),key=operator.itemgetter(0))

简单如下: sorted(dict1, key=dict1.get)

那么,它实际上可以做一个“按字典值排序”。最近我不得不在Code Golf中做这件事(Stack Overflow question

如果您构造一个字典,其中的关键词和每个词的出现次数为值,在此简化为:

fromcollectionsimportdefaultdict

d=defaultdict(int)

forwintext.split():d[w] += 1

那么你可以得到一个单词列表,按使用频率sorted(d, key=d.get)排序 – 排序迭代字典键,使用单词出现次数作为排序键。

forwinsorted(d,key=d.get,reverse=True):

printw,d[w]

我正在写这个详细的解释来说明人们通常所说的“我可以轻松地按键排序字典,但我怎么按价值排序” – 我认为OP正试图解决这个问题。解决方案是根据数值对键进行排序,如上所示。

你可以使用:

sorted(d.items(), key=lambda x: x[1])

这将按字典中的每个条目从最小到最大的值对字典进行排序。

字典不能排序,但你可以从它们建立一个排序列表。

字典值的排序列表:

sorted(d.values())

(键,值)对的列表,按值排序:

fromoperatorimportitemgetter

sorted(d.items(),key=itemgetter(1))

在最近的Python 2.7中,我们有了新的OrderedDict类型,它记住了添加项目的顺序。

>>>d= {"third": 3, "first": 1, "fourth": 4, "second": 2}

>>> fork,vind.items():

... print "%s: %s" % (k,v)

...second: 2fourth: 4third: 3first: 1

>>>d{'second': 2, 'fourth': 4, 'third': 3, 'first': 1}

要从原始中创建一个新的有序字典,按值排序:

>>> fromcollectionsimport OrderedDict

>>>d_sorted_by_value= OrderedDict(sorted(d.items(),key=lambdax:x[1]))

OrderedDict的行为像一个正常的字典:

>>> fork,vind_sorted_by_value.items():

... print "%s: %s" % (k,v)

...first: 1second: 2third: 3fourth: 4

>>>d_sorted_by_valueOrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])

更新:2015年12月5日使用Python 3.5

虽然我发现接受的答案很有用,但我还惊讶于它没有更新为从标准库集合模块中引用

fromoperatorimportitemgetterfromcollectionsimport OrderedDictx= {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)])

官方

# regular unsorted dictionaryd= {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by value

OrderedDict(sorted(d.items(),key=lambdat:t[1]))

# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

使用

importcollectionsPlayer =collections.namedtuple('Player', 'score name')d= {'John':5, 'Alex':10, 'Richard': 7}

先以最低分数排序:

worst=sorted(Player(v,k) for (k,v) ind.items())

以最高得分排序:

best=sorted([Player(v,k) for (k,v) ind.items()],reverse=True)

现在你可以得到它的名字和得分,比如说,我们说第二好的球员(index = 1)非常像Python:

player=best[1]player.name'Richard'player.score7

从Python 3.6开始,内置的字典将会被订购

好消息,所以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))

稍后允许输出为:

fork,vinordered_map.items():

print(k,v)

在这种情况下产生(对于新的Python 3.6 +内置字典!):

foo0bar1baz42

按每个v值的顺序排列。

在我的机器上安装Python 3.5的地方,它现在会产生:

bar1foo0baz42

细节:

正如Raymond Hettinger在2012年提出的(参见python-dev主题为“更紧凑的词典,更快的迭代”),现在(2016年),Victor Stinner在Python-dev的邮件中宣布了Python的Python 3.6 dict变为压缩并获得一个私有版本;而且由于Python 3.6中的问题27350的修复/实现“紧凑且有序的dict”,我们现在可以使用内置的字典来维护插入顺序,因此关键字变得有序!

希望这将导致OrderedDict实现的薄层作为第一步。正如@ JimFasarakis-Hilliard所指出的那样,有些人在将来也会看到OrderedDict类型的用例。我认为,如果这将经得起时间的考验,接下来的步骤是什么,那么Python社区将会仔细检查。

现在是时候重新思考我们的编码习惯,不要错过稳定排序开放的可能性:

关键字参数和

(中级)dict存储

第一个是因为它在某些情况下简化了函数和方法的实现。

第二,它鼓励更容易地使用dicts作为处理管道中的中间存储。

Raymond Hettinger亲切地提供了解释“ The Python Behind Python 3.6 Dictionaries ”的文档- 来自他的旧金山Python Meetup Group发布的2016-DEC-08。

也许一些Stack Overflow高级问答页面会收到这些信息的变体,许多高质量的答案也需要每个版本的更新。

警惕Emptor(但也见下文更新2017-12-15):

正如@ajcr正确地指出:“这个新实现的顺序保留方面被认为是一个实现细节,不应该依赖。” (来自whatsnew36)没有挑选,但引用被削减了一点悲观;-)。它继续为“(这可能会在未来发生变化,但希望在将语言规范更改为强制顺序保留语义之前,在少数版本中使用该语言实现此新的dict;这也是所有当前和未来Python实现的保留语义有助于保持与旧版本语言的向后兼容性,即随机迭代顺序仍然有效,例如Python 3.5)。“

正如在一些人类语言(例如德语)中那样,用法形成了语言,意志现在已经被宣布……在whatsnew36中。

2017-12-15更新:

在发给python-dev名单的邮件中,Guido van Rossum宣称:

做到这一点。“Dict保持插入顺序”是裁决。谢谢!

因此,dict插入排序的3.6版CPython副作用现在已成为语言规范的一部分(而不仅仅是一个实现细节)。collections.OrderedDict正如Raymond Hettinger在讨论中提醒的那样,该邮件线程还提供了一些可区分的设计目标。

我遇到了同样的问题,我解决了这个问题:

WantedOutput =sorted(MyDict,key=lambdax: MyDict[x])

(回答“不可能排序字典”的人没有读到这个问题!事实上,“我可以对键进行排序,但是我怎样才能根据这些值进行排序?”显然意味着他想要一个列表按照它们的值的值排序的键)。

请注意订单没有被很好地定义(在输出列表中,具有相同值的键将以任意顺序)。

这是代码:

importoperator

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 >>"

forfooinorigin_list:

printfooprint "\n>> Rofl sort >>"

forfooinsorted(origin_list,key=operator.itemgetter("rofl")):

printfooprint "\n>> Rank sort >>"

forfooinsorted(origin_list,key=operator.itemgetter("rank")):

printfoo

结果如下:

原版的

{'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}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值