Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 根据多个子字典值对字典进行排序_Python_Sorting_Dictionary - Fatal编程技术网

Python 根据多个子字典值对字典进行排序

Python 根据多个子字典值对字典进行排序,python,sorting,dictionary,Python,Sorting,Dictionary,我有一本这样的字典: myDict = { 'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'}, 'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'}, 'SER12345': {'serial_num': 'SER12345', 'site_location': 'North Ameri

我有一本这样的字典:

myDict = {
    'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'},
    'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'},
    'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'},
    'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'},
    'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'}
}
我的目标是按照每个子词典的
site\u位置
serial\u num
对该词典进行排序

使用我在这个问题中找到的代码--我能够对它进行排序,但这并不是我所期望的

这是我的代码:

import pprint
items = ((k, k2, v) for k in myDict for k2, v in myDict[k].items())
ordered = sorted(items, key=lambda x:x[-1], reverse=False)
pprint.pprint(ordered)
这是我得到的结果:

[('ABC12346', 'site_location', 'Europe'),
 ('SER12345', 'site_location', 'North America'),
 ('SER12346', 'site_location', 'North America'),
 ('SER12347', 'site_location', 'South America'),
 ('ABC12345', 'site_location', 'South America'),
 ('ABC12346', 'serial_num': 'ABC12346'),
 ('SER12345', 'serial_num': 'SER12345'),
 ('SER12346', 'serial_num': 'SER12346'),
 ('SER12347', 'serial_num': 'SER12347'),
 ('ABC12345', 'serial_num': 'ABC12345')]
不过,我期待的是更像这样的事情:

{
    'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'}
    'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'},
    'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'},
    'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'},
    'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'},
}

实际结果是分离序列号和站点位置。我想把它们放在排序对象中。我怎么做?这是你想要的吗

dicts = [{k: v} for (k,v) in myDict.items()]
dicts.sort(key=lambda d: (d.values()[0]['site_location'], d.values()[0]['serial_num'],))
用于执行的输出:

import pprint
pprint.pprint(dicts)
是:

编辑:我正在回答你关于输出格式的问题,但这可能更有意义:

dicts = myDict.items()
dicts.sort(key=lambda (k,d): (d['site_location'], d['serial_num'],))
输出:

[('ABC12346', {'serial_num': 'ABC12346', 'site_location': 'Europe'}),
 ('SER12345', {'serial_num': 'SER12345', 'site_location': 'North America'}),
 ('SER12346', {'serial_num': 'SER12346', 'site_location': 'North America'}),
 ('ABC12345', {'serial_num': 'ABC12345', 'site_location': 'South America'}),
 ('SER12347', {'serial_num': 'SER12347', 'site_location': 'South America'})]

这是你想要的吗

dicts = [{k: v} for (k,v) in myDict.items()]
dicts.sort(key=lambda d: (d.values()[0]['site_location'], d.values()[0]['serial_num'],))
用于执行的输出:

import pprint
pprint.pprint(dicts)
是:

编辑:我正在回答你关于输出格式的问题,但这可能更有意义:

dicts = myDict.items()
dicts.sort(key=lambda (k,d): (d['site_location'], d['serial_num'],))
输出:

[('ABC12346', {'serial_num': 'ABC12346', 'site_location': 'Europe'}),
 ('SER12345', {'serial_num': 'SER12345', 'site_location': 'North America'}),
 ('SER12346', {'serial_num': 'SER12346', 'site_location': 'North America'}),
 ('ABC12345', {'serial_num': 'ABC12345', 'site_location': 'South America'}),
 ('SER12347', {'serial_num': 'SER12347', 'site_location': 'South America'})]

我有一个使用
cmp
的解决方案(我认为您必须使用该解决方案,因为我们使用了两个键的组合),但它不是很漂亮,我想它可以改进:

>>> pprint(sorted(myDict.items(), cmp=lambda x, y: cmp((x[1]['site_location'], x[1]['serial_num']), (y[1]['site_location'], y[1]['serial_num']))))
[('ABC12346', {'serial_num': 'ABC12346', 'site_location': 'Europe'}),
 ('SER12345', {'serial_num': 'SER12345', 'site_location': 'North America'}),
 ('SER12346', {'serial_num': 'SER12346', 'site_location': 'North America'}),
 ('ABC12345', {'serial_num': 'ABC12345', 'site_location': 'South America'}),
 ('SER12347', {'serial_num': 'SER12347', 'site_location': 'South America'})]

我有一个使用
cmp
的解决方案(我认为您必须使用该解决方案,因为我们使用了两个键的组合),但它不是很漂亮,我想它可以改进:

>>> pprint(sorted(myDict.items(), cmp=lambda x, y: cmp((x[1]['site_location'], x[1]['serial_num']), (y[1]['site_location'], y[1]['serial_num']))))
[('ABC12346', {'serial_num': 'ABC12346', 'site_location': 'Europe'}),
 ('SER12345', {'serial_num': 'SER12345', 'site_location': 'North America'}),
 ('SER12346', {'serial_num': 'SER12346', 'site_location': 'North America'}),
 ('ABC12345', {'serial_num': 'ABC12345', 'site_location': 'South America'}),
 ('SER12347', {'serial_num': 'SER12347', 'site_location': 'South America'})]

字典不保留项目的顺序-因此无法排序。如果您想要排序字典的外观,您需要创建一个排序列表,然后将其插入OrderedDict类中。下面的代码片段说明了这一点:

from collections import OrderedDict

myDict = {
    'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'},
    'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'},
    'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'},
    'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'},
    'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'}
}

def sortfun(d):
    return (d[1]['site_location'], d[1]['serial_num'])

skv = sorted(myDict.iteritems(), key=sortfun)
sorted_dict = OrderedDict(skv)

print sorted_dict

字典不保留项目的顺序-因此无法排序。如果您想要排序字典的外观,您需要创建一个排序列表,然后将其插入OrderedDict类中。下面的代码片段说明了这一点:

from collections import OrderedDict

myDict = {
    'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'},
    'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'},
    'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'},
    'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'},
    'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'}
}

def sortfun(d):
    return (d[1]['site_location'], d[1]['serial_num'])

skv = sorted(myDict.iteritems(), key=sortfun)
sorted_dict = OrderedDict(skv)

print sorted_dict

最后一个代码段不是有效的python-列表中不能有键。@thg435,你是对的。这是因为缺少对轮班的控制。那本应该是一本字典,但我很乐意以这种方式订购任何东西。元组列表或类似的列表对我来说是可以的。@Andy如果您想要排序字典结构,请使用OrderedDict,如下所示。最后一个代码段不是有效的python-列表中不能有键。@thg435,您是对的。这是因为缺少对轮班的控制。那本应该是一本字典,但我很乐意以这种方式订购任何东西。一个元组列表或类似的列表对我来说没问题。@Andy如果你想要排序字典结构,请使用如下所示的OrderedDict。使用
更干净。您所做的一切本质上就是对
key
将返回的两个值执行
cmp
,但这些值不会被缓存(就像它们对
key
所做的那样)。它工作的原因是元组会按照您认为的方式进行比较,因此如果
key
返回一个元组,它会比较多个值。使用
key
更简洁。您所做的一切本质上就是对
key
将返回的两个值执行
cmp
,但这些值不会被缓存(就像它们对
key
所做的那样)。它工作的原因是元组以您认为的方式进行比较,因此如果
key
返回一个元组,它比较多个值。您只需从
sortfun
@Claudiu Good point返回一个元组-看起来更干净-上面更新您只需从
sortfun
@Claudiu Good point返回一个元组-看起来更干净-上面更新的元组示例,我怎样才能按
站点位置
而不是序列号进行排序?@Andy:哦,我错了,编辑过了。在元组示例中,它应该是
(d['site\u location',d['serial\u num'])
,而不是
(k,d['site\u location',d['serial\u num'])
,在元组示例中,我如何按
site\u location
而不是序列号排序?@Andy:哦,我的错了,编辑了它。它应该是
(d['site\u location',d['serial\u num'])
,而不是
(k,d['site\u location',d['serial\u num'])