字典排序
基础版
按照字典的key或value排序
# 字典如下:
mydict1 = {'b': 3, 'd': 1, 'c': 2, 'a': 4}
mydict2 = {'name': '张三', 'age': '18岁', 'city': '深圳', 'tel': '13626266627'}
print('字典mydict1排序前:', mydict1)
print('字典mydict2排序前:', mydict2)
print()
print('按照字典的key排序:')
print()
def func1(mydict):
"""
方法一:
思路是将k和v以元组的形式组成列表并排序(会以元组的第一个元素的大小排序,即k),再遍历列表取出元组,
元组中的元素分别是k和v,放到一个新的字典里,最后返回这个新字典
"""
mydict2list = sorted([item for item in mydict.items()]) # 目的是将字典变成列表再用sorted()排序
new_dict = {} #
for i in mydict2list: # 遍历出来的i是一个元祖,包含key和value两个元素
new_dict[i[0]] = i[1]
print('方法一排序后:', new_dict)
func1(mydict1)
func1(mydict2)
print()
def func2(mydict):
"""
方法二:
用的还是方法一的思路,但是sorted()函数的返回值就是一个列表,所以不需要写列表推导式
即sorted([item for item in mydict.items()])可以简写成sorted(mydict.items())
"""
mydict2list = sorted(mydict.items())
new_dict = {}
for i in mydict2list:
new_dict[i[0]] = i[1]
print('方法二排序后:', new_dict)
func2(mydict1)
func2(mydict2)
print()
def func3(mydict):
"""
方法三:
mydict2list是一个列表,列表内的元素是一个个的元组,元组里包含两个元素
分别是原始字典中的key和value,而dict()这个方法可以转化这种结构成字典
所以将for循环省略,写成下面的方法
"""
mydict2list = sorted(mydict.items())
new_dict = dict(mydict2list)
print('方法三排序后:', new_dict)
func3(mydict1)
func3(mydict2)
print()
def func4(mydict):
"""
方法四:
方法三中的两行代码可以合并成一行
"""
print('方法四排序后:', dict(sorted(mydict.items())))
func4(mydict1)
func4(mydict2)
print()
print("""
总结下来,字典按照key排序的格式是:
dict(sorted(mydict.items()))
即,最外层是dict(),中间层是sorted(),最内层是被排序字典.items()
最终结果就是:dict(sorted(mydict.items())))
""")
print()
print('拓展:只要列表或者元祖中的元素,是成对儿出现的,都可以使用dict()将其转化成字典,例如:')
mylist = [['a', 1], ['b', 2], ('c', [4])]
print('列表:', mylist)
print('列表转字典:', dict(mylist))
mytuple = (['a', 1], [('b',), 2], ('c', [4]))
print('元组:', mytuple)
print('元组转字典:', dict(mytuple))
print()
def func5(mydict):
"""
方法五:
其中sorted()方法有个参数是key,可以指定参与比较的元素
可以使用lambda函数来返回参与比较的元素,上述代码可以写成这样:
"""
print('方法五排序后:', dict(sorted(mydict.items(), key=lambda x: x[0]))) # 对比方法四,发现key这个参数加不加都可以,加上的目的是为了引出后面的按照value排序
func5(mydict1)
func5(mydict2)
print()
print("""从方法一到方法四
总结出字典排序的核心语句是:sorted(mydict.items())
而方法五的核心语句是:sorted(mydict.items(),key=lambda x:x[0])
在sorted()方法中添加了一个参数key,表示排序条件是lambda x:x[0]
解释:
匿名函数 lambda x:y 中x表示传入的参数,y表示lambda 函数的返回值
所以 lambda x:x[0] 表示传入参数x返回参数x的第一个元素,即x[0]
而字典的items()方法将字典的k和v转化为了元组,并且被当作参数传给了lambda的x
x的结构是(k,v),x[0]就是k,也就是用字典的key作为排序条件
为了更加方便的理解匿名函数lambda,可以改写成正常的函数, 并输出x、x[0]的结果和类型
""")
def mykey(x):
print('x及x的类型到底什么:', x, type(x))
print('x[0]及x[0]的类型到底什么:', x[0], type(x[0]))
return x[0]
print('方法五排序后:', dict(sorted(mydict1.items(), key=mykey)))
print('')
print('方法五排序后:', dict(sorted(mydict2.items(), key=mykey)))
print('')
print('从上面的输出结果可以看出x[0]就是字典的key值')
# 如此一来按照value排序只要把x[0]改成x[1]即可:
print('按照字典的value排序:')
print('排序后:', dict(sorted(mydict1.items(), key=lambda x: x[1])))
print('排序后:', dict(sorted(mydict2.items(), key=lambda x: x[1])))
print("""
按照value排序后发现“张三”在“深圳”前面
原因是python以较汉字的utf-8的编码值排序的
使用ord()方法可以得到汉族的Unicode编码(10进制)
ord('张')得出24352,ord('深')得出28145
所以‘张’排在‘深’前面
或者使用 '张'.encode() 得出E5BCA0,'深'.encode() 得出E6B7B1,比较16进制也能看出大小
""")
# 那么对于嵌套的字典结构如何排序呢?
dit = {
'd': {'sort': 7},
'a': {'sort': 3},
'c': {'sort': 4},
'b': {'sort': 1},
}
print('字典嵌套字典,按照被嵌套字典的key排序,即abcd排序:')
print('原始顺序:', dit)
print('按照key排序:', dict(sorted(dit.items(), key=lambda x: x[0])))
print('字典嵌套字典,按照被嵌套字典的value排序,即1347排序:')
print('按照key排序:', dict(sorted(dit.items(), key=lambda x: x[1]['sort'])))
print('')
print("为了方便理解,再次把lambda改写成正常的函数,并输出x[1]['sort']的值:")
def value(x):
print(x, x[1], x[1]['sort'])
return x[1]['sort']
print('按照value排序:', dict(sorted(dit.items(), key=value)))
print()
# 还是嵌套字典,但是嵌套字典的key不一样呢?
dit = {
'd': {'sortd': 7},
'a': {'sorta': 3},
'c': {'sortc': 4},
'b': {'sortb': 1},
}
def value(x):
"""
这种情况下,就不能使用x[1]['sort'],因为被嵌套的字典的key不是统一的'sort',所以要通过字典的values()取出所有的key,
但是values()的类型是dict_values,不能通过索引取出value,所以要转成列表
即list(x[1].values()),此时的列表就一个元素,通过索引就能取出来
最终的形式就是list(x[1].values())[0]
"""
print(x[1], x[1].values(), list(x[1].values())[0])
return list(x[1].values())[0]
print('按照value排序:', dict(sorted(dit.items(), key=value)))
print()
# 既然核心代码是list(x[1].values())[0],那么最终的写法就是:
print('按照value排序:', dict(sorted(dit.items(), key=lambda x: list(x[1].values())[0])))
输出:
字典mydict1排序前: {'b': 3, 'd': 1, 'c': 2, 'a': 4}
字典mydict2排序前: {'name': '张三', 'age': '18岁', 'city': '深圳', 'tel': '13626266627'}
按照字典的key排序:
方法一排序后: {'a': 4, 'b': 3, 'c': 2, 'd': 1}
方法一排序后: {'age': '18岁', 'city': '深圳', 'name': '张三', 'tel': '13626266627'}
方法二排序后: {'a': 4, 'b': 3, 'c': 2, 'd': 1}
方法二排序后: {'age': '18岁', 'city': '深圳', 'name': '张三', 'tel': '13626266627'}
方法三排序后: {'a': 4, 'b': 3, 'c': 2, 'd': 1}
方法三排序后: {'age': '18岁', 'city': '深圳', 'name': '张三', 'tel': '13626266627'}
方法四排序后: {'a': 4, 'b': 3, 'c': 2, 'd': 1}
方法四排序后: {'age': '18岁', 'city': '深圳', 'name': '张三', 'tel': '13626266627'}
总结下来,字典按照key排序的格式是:
dict(sorted(mydict.items()))
即,最外层是dict(),中间层是sorted(),最内层是被排序字典.items()
最终结果就是:dict(sorted(mydict.items())))
拓展:只要列表或者元祖中的元素,是成对儿出现的,都可以使用dict()将其转化成字典,例如:
列表: [['a', 1], ['b', 2], ('c', [4])]
列表转字典: {'a': 1, 'b': 2, 'c': [4]}
元组: (['a', 1], [('b',), 2], ('c', [4]))
元组转字典: {'a': 1, ('b',): 2, 'c': [4]}
方法五排序后: {'a': 4, 'b': 3, 'c': 2, 'd': 1}
方法五排序后: {'age': '18岁', 'city': '深圳', 'name': '张三', 'tel': '13626266627'}
从方法一到方法四
总结出字典排序的核心语句是:sorted(mydict.items())
而方法五的核心语句是:sorted(mydict.items(),key=lambda x:x[0])
在sorted()方法中添加了一个参数key,表示排序条件是lambda x:x[0]
解释:
匿名函数 lambda x:y 中x表示传入的参数,y表示lambda 函数的返回值
所以 lambda x:x[0] 表示传入参数x返回参数x的第一个元素,即x[0]
而字典的items()方法将字典的k和v转化为了元组,并且被当作参数传给了lambda的x
x的结构是(k,v),x[0]就是k,也就是用字典的key作为排序条件
为了更加方便的理解匿名函数lambda,可以改写成正常的函数, 并输出x、x[0]的结果和类型
x及x的类型到底什么: ('b', 3) <class 'tuple'>
x[0]及x[0]的类型到底什么: b <class 'str'>
x及x的类型到底什么: ('d', 1) <class 'tuple'>
x[0]及x[0]的类型到底什么: d <class 'str'>
x及x的类型到底什么: ('c', 2) <class 'tuple'>
x[0]及x[0]的类型到底什么: c <class 'str'>
x及x的类型到底什么: ('a', 4) <class 'tuple'>
x[0]及x[0]的类型到底什么: a <class 'str'>
方法五排序后: {'a': 4, 'b': 3, 'c': 2, 'd': 1}
x及x的类型到底什么: ('name', '张三') <class 'tuple'>
x[0]及x[0]的类型到底什么: name <class 'str'>
x及x的类型到底什么: ('age', '18岁') <class 'tuple'>
x[0]及x[0]的类型到底什么: age <class 'str'>
x及x的类型到底什么: ('city', '深圳') <class 'tuple'>
x[0]及x[0]的类型到底什么: city <class 'str'>
x及x的类型到底什么: ('tel', '13626266627') <class 'tuple'>
x[0]及x[0]的类型到底什么: tel <class 'str'>
方法五排序后: {'age': '18岁', 'city': '深圳', 'name': '张三', 'tel': '13626266627'}
从上面的输出结果可以看出x[0]就是字典的key值
按照字典的value排序:
排序后: {'d': 1, 'c': 2, 'b': 3, 'a': 4}
排序后: {'tel': '13626266627', 'age': '18岁', 'name': '张三', 'city': '深圳'}
按照value排序后发现“张三”在“深圳”前面
原因是python以较汉字的utf-8的编码值排序的
使用ord()方法可以得到汉族的Unicode编码(10进制)
ord('张')得出24352,ord('深')得出28145
所以‘张’排在‘深’前面
或者使用 '张'.encode() 得出E5BCA0,'深'.encode() 得出E6B7B1,比较16进制也能看出大小
字典嵌套字典,按照被嵌套字典的key排序,即abcd排序:
原始顺序: {'d': {'sort': 7}, 'a': {'sort': 3}, 'c': {'sort': 4}, 'b': {'sort': 1}}
按照key排序: {'a': {'sort': 3}, 'b': {'sort': 1}, 'c': {'sort': 4}, 'd': {'sort': 7}}
字典嵌套字典,按照被嵌套字典的value排序,即1347排序:
按照key排序: {'b': {'sort': 1}, 'a': {'sort': 3}, 'c': {'sort': 4}, 'd': {'sort': 7}}
为了方便理解,再次把lambda改写成正常的函数,并输出x[1]['sort']的值:
('d', {'sort': 7}) {'sort': 7} 7
('a', {'sort': 3}) {'sort': 3} 3
('c', {'sort': 4}) {'sort': 4} 4
('b', {'sort': 1}) {'sort': 1} 1
按照value排序: {'b': {'sort': 1}, 'a': {'sort': 3}, 'c': {'sort': 4}, 'd': {'sort': 7}}
{'sortd': 7} dict_values([7]) 7
{'sorta': 3} dict_values([3]) 3
{'sortc': 4} dict_values([4]) 4
{'sortb': 1} dict_values([1]) 1
按照value排序: {'b': {'sortb': 1}, 'a': {'sorta': 3}, 'c': {'sortc': 4}, 'd': {'sortd': 7}}
按照value排序: {'b': {'sortb': 1}, 'a': {'sorta': 3}, 'c': {'sortc': 4}, 'd': {'sortd': 7}}
困难版
上面都是直接排序字典, 如果数据是列表中包含多个字典, 例如:
li = [{'k': 1, 'v': 2}, {'k': 12, 'v': 222}, {'k': 13, 'v': 32}]
正常函数就是:
def my_sort(x):
# print(x)
return x.get('k')
按照key和value倒序就是:
print(sorted(li, key=my_sort, reverse=True))
print(sorted(li, key=lambda x: x.get('v'), reverse=True))
输出:
[{'k': 13, 'v': 32}, {'k': 12, 'v': 222}, {'k': 1, 'v': 2}]
[{'k': 12, 'v': 222}, {'k': 13, 'v': 32}, {'k': 1, 'v': 2}]
困难版Plus
列表中每个元素的key和value的值都不一样
li = [{'k1': 1, 'v1': 2}, {'k2': 12, 'v2': 222}, {'k3': 13, 'v2': 32}]
正常的函数就是:
def my_sort(x):
# print(list(x.items()))
return list(x.items())[0][1]
按照key和value倒序就是:
print(sorted(li, key=my_sort, reverse=True))
print(sorted(li, key=lambda x: list(x.items())[1][1], reverse=True))
输出:
[{'k3': 13, 'v2': 32}, {'k2': 12, 'v2': 222}, {'k1': 1, 'v1': 2}]
[{'k2': 12, 'v2': 222}, {'k3': 13, 'v2': 32}, {'k1': 1, 'v1': 2}]