【问题标题】:Sorting a list of dictionaries in Python 3在 Python 3 中对字典列表进行排序
【发布时间】:2018-05-27 12:05:12
【问题描述】:

我正在尝试对字典列表进行排序。我的目标是以相同的方式对具有多个(可能相同)键的字典进行排序,即使字典的顺序不同或字典中的键顺序不同。

在 Python 2 中,我使用了以下内容:

a = [{1: 2, 7: 8}, {7: 8, 3: 4}, {5: 6}]
b = [{3: 4, 7: 8}, {7: 8, 1: 2}, {5: 6}]
a.sort()
b.sort()
a
Out[20]: [{5: 6}, {1: 2, 7: 8}, {3: 4, 7: 8}]
b
Out[21]: [{5: 6}, {1: 2, 7: 8}, {3: 4, 7: 8}]

这成功实现了我创建两个看起来完全相同的排序字典的目标。

我正在尝试在 Python 3 中做同样的事情,其中​​ .sort() 不适用于字典列表。

我尝试了不同的方法。

1.

sorted(a, key=lambda d: max(d.keys()))

这不起作用:

a = [{1: 2, 7: 8}, {3: 4, 7: 8}, {5: 6}]
b = [{3: 4, 7: 8}, {1: 2, 7: 8}, {5: 6}]
a2 = sorted(a, key=lambda d: max(d.keys()))
b2 = sorted(b, key=lambda d: max(d.keys()))
a2
Out[1]: [{5: 6}, {1: 2, 7: 8}, {7: 8, 3: 4}]
b2
Out[2]: [{5: 6}, {3: 4, 7: 8}, {7: 8, 1: 2}]

2.

a2 = sorted([list(zip(x.keys(),x.values())) for x in a])
a3 = [{k: v for (k,v) in x} for x in a2]

这不起作用:

a = [{1: 2, 7: 8}, {7: 8, 3: 4}, {5: 6}]
b = [{3: 4, 7: 8}, {7: 8, 1: 2}, {5: 6}]
a2 = sorted([list(zip(x.keys(),x.values())) for x in a])
a3 = [{k: v for (k,v) in x} for x in a2]
b2 = sorted([list(zip(x.keys(),x.values())) for x in b])
b3 = [{k: v for (k,v) in x} for x in b2]
a3
Out[1]: [{1: 2, 7: 8}, {5: 6}, {7: 8, 3: 4}]
b3
Out[2]: [{3: 4, 7: 8}, {5: 6}, {7: 8, 1: 2}]

有人知道如何在 Python 3 中获得 Python 2 的结果吗??

【问题讨论】:

  • 在python2中,几乎任何对象都可以进行比较,这意味着任何东西都可以排序。在您的情况下,排序是完全任意的。在 python3 中,有问题的对象必须是兼容的。如果没有,您需要提供排序键。
  • 您是想根据每个字典中的键值对的数量对字典进行排序,还是按已排序键的列表或什至其他东西进行排序。一旦你确定了你希望如何进行排序,你就可以编写适当的排序代码。
  • 我认为您的问题的关键是准确了解您希望如何对列表进行排序。说“我的目标是用多个键以相同的方式”对字典进行排序是不够的。此外,您无法对字典本身进行排序 - 您看到的是随机排列的项目。您的示例适用于您的特定键和值集,但会为其他值生成“未排序”字典。
  • 我的目标只是以同样的方式对它们进行排序。我想确保它可以以相同的方式对任何键和值的组合进行排序。关于排序本身如何发生的唯一偏好是需要多长时间。我希望它灵活(因此可以处理任何键和值)且速度快。
  • 我已经设法编写了几段可以做我想做的代码,但这一切都需要很长时间。当使用 .sort 循环超过 8000 个条目时,我使用排序的函数需要 2.5 秒,但在为它编写自己的函数时,我只设法在大约 60 秒内完成。这是我正在寻找单线的主要原因,就像这里已经建议的那样。

标签: python python-3.x list sorting dictionary


【解决方案1】:

可以通过以下方式对字典中的所有keys 进行排序:

a.sort(key=lambda d: d.keys())
b.sort(key=lambda d: d.keys())

要获得您想要的结果,我们需要按升序对键进行排序,如下所示:

a.sort(key=lambda d: sorted(list(d.keys()), reverse=True))
b.sort(key=lambda d: sorted(list(d.keys()), reverse=True))

这给出了以下结果:

>>> a
[{5: 6}, {1: 2, 7: 8}, {3: 4, 7: 8}]
>>> b
[{5: 6}, {1: 2, 7: 8}, {3: 4, 7: 8}]

编辑:为了也根据值进行排序(在 cmets 中询问),以下可能有效:

a.sort(key=lambda d: sorted(list(d.keys()) + sorted(list(d.values())), reverse=True))
b.sort(key=lambda d: sorted(list(d.keys()) + sorted(list(d.values())), reverse=True))

【讨论】:

  • (所以我知道我的问题并未完全涵盖这种情况,但是)当有 2 个字典具有相同的键但值不同时,此解决方案不起作用。如果你有 a = [{1: 2},{1: 3}] 和 b = [{1: 3},{1: 2}] 它会保持这两个列表的原始顺序,而不是 Python 2 .sort确实(这使两个列表 [{1: 2},{1: 3}])
【解决方案2】:

排序时需要使用每个dict的所有item,d.items()以任意顺序迭代item,所以需要排序。这是您的排序键:

a = [{1: 2, 7: 8}, {7: 8, 3: 4}, {5: 6}]
b = [{3: 4, 7: 8}, {7: 8, 1: 2}, {5: 6}]
sorted(a, key=lambda d: sorted(d.items()))
Out: [{1: 2, 7: 8}, {3: 4, 7: 8}, {5: 6}]

sorted(b, key=lambda d: sorted(d.items()))
Out: [{1: 2, 7: 8}, {3: 4, 7: 8}, {5: 6}]

x = [{1: 2},{1: 3}]
y = [{1: 3},{1: 2}]
sorted(x, key=lambda d: sorted(d.items()))
Out: [{1: 2}, {1: 3}]

sorted(y, key=lambda d: sorted(d.items()))
Out: [{1: 2}, {1: 3}]

注意sorted(a, key=...) 创建一个新列表,而a.sort(key=...) 进行就地排序。

【讨论】:

  • 这绝对完美,非常感谢! .sort 给我的结果相同,速度一样快(甚至快一点),并且在 Python 2 和 3 中都能完美运行。非常感谢!!!
  • 再次向人们解释为什么这可以解决我的问题而 ikkuh 的解决方案不能:Pavlo 的解决方案也始终在两个具有相同键但不同值的字典之间进行排序。
  • 有人能解释一下这里的排序是如何工作的吗?
猜你喜欢
  • 2011-12-22
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 2015-05-29
  • 1970-01-01
相关资源
最近更新 更多