如何基于子字典的两个值对字典嵌套字典进行排序?
key1 and key3) Let's start by fixing the error in your original code, then implement the multi-field sorting you need.
Why Your First Code Failed
That TypeError happened because your lambda had a misstep:
i[1]['key1']grabs a string value (like"dog"or"apple")- Adding
[1]to that pulls the second character of the string (e.g.,"o"from"dog") - Trying to access
['key3']on a single character (a string) doesn't work—strings only accept integer indices, not string keys like'key3'.
The Fix: Sort with a Tuple of Fields
To sort by both key1 and key3, you just need to return a tuple of these two values in your lambda. Python sorts tuples lexicographically: first by the first element, then by the second if there are ties in the first.
Here's the corrected working code:
from collections import OrderedDict test_dict = {'test1':{'key1': 'dog', 'key2': 'dennis', 'key3': 'bbb'}, 'test2':{'key1': 'apple', 'key2': 'arthur', 'key3': 'fff'}, 'test3':{'key1': 'bear', 'key2': 'bernard', 'key3': 'xxx'}, 'test4':{'key1': 'elephant', 'key2': 'eric', 'key3': 'rrr'}, 'test5':{'key1': 'cat', 'key2': 'charlie', 'key3': 'lll'} } # Sort by key1 first, then key3 sorted_dict = OrderedDict(sorted(test_dict.items(), key=lambda i: (i[1]['key1'], i[1]['key3']))) for key, value in sorted_dict.items(): print(key, value)
What This Does
When you run this, the entries will first be sorted alphabetically by key1. If any entries had identical key1 values (none in your sample), those would then be sorted by key3. For your test data, the output will be:
test2 {'key1': 'apple', 'key2': 'arthur', 'key3': 'fff'} test3 {'key1': 'bear', 'key2': 'bernard', 'key3': 'xxx'} test5 {'key1': 'cat', 'key2': 'charlie', 'key3': 'lll'} test1 {'key1': 'dog', 'key2': 'dennis', 'key3': 'bbb'} test4 {'key1': 'elephant', 'key2': 'eric', 'key3': 'rrr'}
Bonus: Customizing Sort Order
If you want to reverse the sort for one of the fields (e.g., sort key1 ascending but key3 descending), here's how to handle it:
- For numeric values, you could use a negative sign (e.g.,
(i[1]['key1'], -i[1]['key3'])ifkey3was a number) - For strings, you can reverse the string itself in the lambda, or use Python's stable sort behavior. For example:
Or, use a two-step sort to preserve order for ties:# Sort key1 ascending, key3 descending sorted_dict = OrderedDict(sorted(test_dict.items(), key=lambda i: (i[1]['key1'], i[1]['key3'][::-1])))# First sort by key3 descending temp_sorted = sorted(test_dict.items(), key=lambda i: i[1]['key3'], reverse=True) # Then sort by key1 ascending (preserves key3 order for matching key1 values) sorted_dict = OrderedDict(sorted(temp_sorted, key=lambda i: i[1]['key1']))
内容的提问来源于stack exchange,提问作者gdogg371

