在python中按值对defaultdict进行排序

Posted

技术标签:

【中文标题】在python中按值对defaultdict进行排序【英文标题】:Sorting a defaultdict by value in python 【发布时间】:2012-04-28 23:57:24 【问题描述】:

我有一个类似这样的数据结构:

三个城市不同年份的人口如下。

Name  1990 2000 2010
A     10   20   30
B     20   30   10
C     30   10   20

我正在使用defaultdict 来存储数据。

from collections import defaultdict
cityPopulation=defaultdict(list)
cityPopulation['A']=[10,20,30]
cityPopulation['B']=[20,30,10]
cityPopulation['C']=[30,10,20]

我想根据列表的特定列(年份)对defaultdict 进行排序。 比如说,1990 年的排序应该给出C,B,A,而 2010 年的排序应该给出A,C,B

另外,这是存储数据的最佳方式吗?当我改变人口值时,我希望它是可变的。

【问题讨论】:

您想存储排序后的字典以备将来使用,还是直接输出?您可能想查看ordereddict 和namedtuple。 我只想打印订单。 为什么2010 的排序会给出A,B,C 好吧,你仍然很可能想要一个有序的数据结构。 我不希望对数据结构进行排序,因为顺序取决于年份。 【参考方案1】:

如果您想根据值而不是键进行排序,请使用data.items() 并将键设置为lambda kv: kv[1],以便它选择值。


查看带有此defaultdict 的示例:

>>> from collections import defaultdict
>>> data = defaultdict(int)
>>> data['ciao'] = 17
>>> data['bye'] = 14
>>> data['hello'] = 23

>>> data
defaultdict(<type 'int'>, 'ciao': 17, 'bye': 14, 'hello': 23)

现在,让我们按值排序:

>>> sorted(data.items(), lambda kv: kv[1])
[('bye', 14), ('ciao', 17), ('hello', 23)]

如果您希望更大的数字先出现,最后使用reverse=True

>>> sorted(data.items(), lambda kv: kv[1], reverse=True)
[('hello', 23), ('ciao', 17), ('bye', 14)]

请注意,key=lambda(k,v): v 是(对我而言)更清晰的表达 key=lambda(v): v[1] 的方式,只是后者是 Python 3 允许它的唯一方式,因为 auto tuple unpacking in lambda is not available。

在 Python 2 中,您可以说:

>>> sorted(d.items(), key=lambda(k,v): v)
[('bye', 14), ('ciao', 17), ('hello', 23)]

【讨论】:

TypeError: sorted expected 1 argument, got 2. Needed to add key=【参考方案2】:

迟到的答案,而不是对问题的直接答案,但如果您最终从“在 python 中按值排序默认字典”谷歌搜索,这就是我 sort 的方式(普通的 python 字典无法排序,但可以打印排序)defaultdict 按其值:

orders = 
    'cappuccino': 54,
    'latte': 56,
    'espresso': 72,
    'americano': 48,
    'cortado': 41


sort_orders = sorted(orders.items(), key=lambda x: x[1], reverse=True)

for i in sort_orders:
    print(i[0], i[1])

【讨论】:

【参考方案3】:
>>> sorted(cityPopulation.iteritems(),key=lambda (k,v): v[0],reverse=True) #1990
[('C', [30, 10, 20]), ('B', [20, 30, 10]), ('A', [10, 20, 30])]
>>> sorted(cityPopulation.iteritems(),key=lambda (k,v): v[2],reverse=True) #2010
[('A', [10, 20, 30]), ('C', [30, 10, 20]), ('B', [20, 30, 10])]

注意在 python 3 中你不能自动解压 lambda 参数,所以你必须更改代码

sorted(cityPopulation.items(), key=lambda k_v: k_v[1][2], reverse=True) #2010

【讨论】:

非常感谢。这非常接近我想要的。有没有办法按它们所代表的年份来调用或命名列? 如果我有上面的示例数据,我应该如何存储它来实现呢?在实际数据集中,列数(年)约为 100。谢谢。 我不确定实现它的最佳方法。 我已经盯着 Lambdas 好几个月了,你明显而简单的例子终于帮助我理解了它们。谢谢!【参考方案4】:

defaultdict 没有订单。您可能需要使用OrderedDict,或者每次将键排序为一个列表。

例如:

  from operator import itemgetter
  sorted_city_pop = OrderedDict(sorted(cityPopulation.items()))

编辑:如果您只想打印订单,只需使用 sorted 内置:

for key, value in sorted(cityPopulation.items()):
    print(key, value)

【讨论】:

我不想存储订单,只需打印即可。 @sberry 如果你指的是额外的 key 参数,我只是删除了它 - 确实不需要它,因为元组首先排序第一项并且键保证是唯一的。 由于字典中的值是列表,如何按不同的列排序? sberry 的意思是你正在隐藏名为sorted() 的内置函数。 sorted = OrderedDict(sorted(cityPopulation.items()) 行只会工作一次。 @imsc 将 lambda 作为关键参数传递给 sorted 方法,该方法将从每个城市的列表中返回您想要的项目。

以上是关于在python中按值对defaultdict进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中按值对地图进行排序?

在 JavaScript 中按值对字典进行排序

如何在PHP中按值对对象数组进行排序

如何在reactjs / javascript中按值对对象数组进行分组

在 Java 中按值映射自动排序

XSLT muenchian 在子节点中按值分组