【问题标题】:Get sorted list of indices, for a list of dictionaries sorted by a given key获取按给定键排序的字典列表的索引列表
【发布时间】:2015-10-11 13:15:24
【问题描述】:

我有一个包含多个键的字典列表,我想获取多个列表,每个列表都有字典的索引,按特定键排序。

例如,我有以下列表

a = [{"name": "Zoe", "age": 13}, {"name": "Adam", "age": 31}]

我知道我可以做到以下几点

from operator import itemgetter
sorted(a, key=itemgetter("name"))

获取以下信息

[{'name': 'Adam', 'age': 31}, {'name': 'Zoe', 'age': 13}]

但我真的希望能够获得两个带有索引的列表:

[1, 0] # order of the elements in `a` as sorted by name
[0, 1] # order of the elements in `a` as sorted by age

我的真实字典有更多的键值对,我返回 a 和具有按不同键排序的索引的附加列表而不是 a 的多个排序列表对我来说更有效。

【问题讨论】:

  • 那么您到底期望输出什么?列表的列表,其中每个子列表都是排序的a 列表?
  • sorted(a, key=itemgetter("name")) 这部分应该引发NameError。它们与您尝试过的代码完全相同吗?
  • @marmeladze:我想我们可以假设有一个from operator import itemgetter 行。
  • @marmeladze 没有。但 Martjin 已经按照应有的方式修复了它
  • @MartijnPieters 谢谢。我正在快速打字......

标签: python list sorting dictionary


【解决方案1】:

您可以通过生成range() 来生成索引的排序列表,然后调整排序键以将索引从a 列表中的字典转换为特定值:

sorted(range(len(a)), key=lambda i: a[i]['name'])
sorted(range(len(a)), key=lambda i: a[i]['age'])

如果您事先知道键,只需循环并生成多个列表;您也许可以创建一个由每个排序键键入的字典:

{key: sorted(range(len(a)), key=lambda i: a[i][key]) for key in ('name', 'age')}

然后,上面的字典理解使您可以仅根据排序键访问每个排序的列表:

>>> a = [{'name': "Zoe", 'age': 13}, {'name': "Adam", 'age': 31}]
>>> {key: sorted(range(len(a)), key=lambda i: a[i][key]) for key in ('name', 'age')}
{'age': [0, 1], 'name': [1, 0]}

【讨论】:

  • 对于我的例子,我只想有两个列表...一个[1, 0] 和另一个[0, 1]...
  • 试图更清楚...我想要a_sorted_by_name = __SOME_CODE_HEREprint a_sorted_by_name 会打印[1, 0]
  • 这是一个很好的间接排序Martijn的例子!而且我想它与使用 key 函数的任何sort() 一样有效,因为(我假设)它们都是引擎盖下的间接排序。
  • @PM2Ring:是的,两者都是简单的 O(1) 查找。不过,我的版本不需要将索引复制到字典中。 :-P
  • 我已经习惯了Schwartzian transform,以至于我有时会忘记使用更简单、更优雅的方法。 :)
【解决方案2】:

执行此操作的一种简单方法是将索引字段添加到列表中的字典。

from operator import itemgetter

a = [{'name':"Zoe", 'age':13}, {'name':"Adam", 'age':31}]

for i, d in enumerate(a): 
    d['index'] = i

def get_indices(seq):
    return[d['index'] for d in seq]

by_name = sorted(a, key=itemgetter("name"))
print by_name
print get_indices(by_name)

by_age = sorted(a, key=itemgetter("age"))
print by_age
print get_indices(by_age)

输出

[{'index': 1, 'age': 31, 'name': 'Adam'}, {'index': 0, 'age': 13, 'name': 'Zoe'}]
[1, 0]
[{'index': 0, 'age': 13, 'name': 'Zoe'}, {'index': 1, 'age': 31, 'name': 'Adam'}]
[0, 1]

当然,你不需要保留字典的排序列表,你可以这样做

by_name = get_indices(sorted(a, key=itemgetter("name")))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    • 2021-10-27
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    相关资源
    最近更新 更多