我有如下所示的数据结构,并希望对其进行排序 所有子词典都要根据' order'的值进行排序。列。
输入:
to_sort = [
('Fruits',
{
'size': {1:[4, 2, 7,9]},
'name': {1:['Orange', 'Apple', 'Kiwi', 'Mango']},
'color': {1:['Orange', 'Red', 'Brown','Green']},
'order': {1:[2, 1, 4,3]}
}
)
]
输出:
[
('Fruits',
{
'size': {1:[2, 4, 9, 7]},
'name': {1:['Apple', 'Orange', 'Mango', 'Kiwi']},
'color':{1:['Red', 'Orange', 'Green', 'Brown']},
'order':{1:[1, 2, 3, 4]}
}
)
]
我尝试使用lambda
sort = to_sort[1]
print(sorted(sort.items(), key=lambda i: i['order'].values()))
我得到"元组索引必须是整数或切片,而不是str"错误
答案 0 :(得分:1)
假设您可以按照评论中的说明修改数据结构,这对您有用。这是从另一个问题改编而来的:Sorting list based on values from another list?
to_sort = [('Fruits', {
'size': [4, 2, 7,9],
'name': ['Orange', 'Apple', 'Kiwi', 'Mango'],
'color': ['Orange', 'Red', 'Brown','Green'],
'order': [2, 1, 4,3]
})
]
postsort = []
for category, catdata in to_sort:
sorteddata = {}
for name, namedata in catdata.iteritems():
sorteddata[name] = [x for (y,x) in sorted(zip(catdata['order'], namedata))]
postsort.append((category, sorteddata))
print postsort
结果是:
[(
'Fruits',
{
'color': ['Red', 'Orange', 'Green', 'Brown'],
'size': [2, 4, 9, 7],
'order': [1, 2, 3, 4],
'name': ['Apple', 'Orange', 'Mango', 'Kiwi']
}
)]
这可以修改为与现有数据结构一起使用,但如果可能,我建议进行更改。
答案 1 :(得分:1)
您现有的数据结构有点疯狂,但这是我将如何处理它(编辑假设颜色列表的键是123
):
>>> to_sort = [
... ('Fruits',
... {
... 'size': {1:[4, 2, 7,9]},
... 'name': {1:['Orange', 'Apple', 'Kiwi', 'Mango']},
... 'color': {123:['Orange', 'Red', 'Brown','Green']},
... 'order': {1:[2, 1, 4,3]}
... }
... )
... ]
>>> d = to_sort[0][1]
>>> keys = list(d.keys())
>>> idx = keys.index('order')
>>> ordered_kv = zip(keys, zip(*sorted(zip(*(d[k][n] for k in keys for n in d[k])), key = lambda t:t[idx])))
>>> sorted_dict = {k:{n:list(v) for n in d[k]} for k,v in ordered_kv}
>>> from pprint import pprint
>>> pprint(sorted_dict)
{'color': {123: ['Red', 'Orange', 'Green', 'Brown']},
'name': {1: ['Apple', 'Orange', 'Mango', 'Kiwi']},
'order': {1: [1, 2, 3, 4]},
'size': {1: [2, 4, 9, 7]}}
让我们分解一下:首先,我制作了一个规范的密钥列表,并找到了'order'
的索引:
>>> keys = list(to_sort[0][1].keys())
>>> idx = keys.index('order')
下一步是将zip
内部列表组合成元组,其中每个项目共享相同的相对位置:
>>> list(zip(*(d[k][n] for k in keys for n in d[k])))
[(4, 2, 'Orange', 'Orange'), (2, 1, 'Red', 'Apple'), (7, 4, 'Brown', 'Kiwi'), (9, 3, 'Green', 'Mango')]
现在可以根据idx
位置进行排序,然后“解压缩”(这实际上只是意味着再次应用zip-splat组合:
>>> list(zip(*sorted(zip(*(d[k][n] for k in keys for n in d[k])), key=lambda t:t[idx])))
[(2, 4, 9, 7), (1, 2, 3, 4), ('Red', 'Orange', 'Green', 'Brown'), ('Apple', 'Orange', 'Mango', 'Kiwi')]
最后,您使用字典理解重建您的疯狂字典,确保使用原始密钥压缩您的订购值:
>>> ordered_kv = zip(keys, zip(*sorted(zip(*(d[k][n] for k in keys for n in d[k])), key = lambda t:t[idx])))
>>> sorted_dict = {k:{n:list(v) for n in d[k]} for k,v in ordered_kv}
>>> from pprint import pprint
>>> pprint(sorted_dict)
{'color': {123: ['Red', 'Orange', 'Green', 'Brown']},
'name': {1: ['Apple', 'Orange', 'Mango', 'Kiwi']},
'order': {1: [1, 2, 3, 4]},
'size': {1: [2, 4, 9, 7]}}
您应该考虑使用pandas
库来操作这样的数据。观察:
>>> import pandas as pd
>>> df = pd.DataFrame({k: pd.Series(v[1]) for k,v in to_sort[0][1].items()})
>>> df
color name order size
0 Orange Orange 2 4
1 Red Apple 1 2
2 Brown Kiwi 4 7
3 Green Mango 3 9
请注意,我仍然需要将原始数据结构导入到pandas
DataFrame中,但如果您开始使用DataFrame
开始执行任何操作,那么这一切都会变得更加容易。现在你可以做一些很酷的事情:
>>> df.sort_values('order')
color name order size
1 Red Apple 1 2
0 Orange Orange 2 4
3 Green Mango 3 9
2 Brown Kiwi 4 7