文章目录
python之Dict操作(下)
10. Dict排序
1) 根据key对字典排序
根据key,对字典进行排序
推荐写法: 使用Python3的标准库,内置函数:sorted(iterable[, key=None[, reverse=False]),key和reverse是可选参数
- 返回一个排序列表
- iterable用于指定一个可迭代对象,这里是一个字典实例
- key用于指定排序规则,默认是None,语法是key=lambda elem:xxx
- reverse用于指定排序方向,默认是升序,语法是reverse=False/True
dict1 = {"a": 3, "c": 1, "b": 2}
# item指代(键,值)元组,item[0]是键, item[1]是值
# 正序
dict_sorted = sorted(dict1.items(), key=lambda item: item[0])
print(dict_sorted) # [('a', 3), ('b', 2), ('c', 1)]
# 逆序
dict_sorted_rev = sorted(dict1.items(), key=lambda item: item[0], reverse=True)
print(dict_sorted_rev) # [('c', 1), ('b', 2), ('a', 3)]
# ------
# 注意:sorted(dict1)默认是对key排序,而不是对整个字典
sorted1 = sorted(dict1)
print(sorted1) # ['a', 'b', 'c']
2) 根据key对value排序
根据字典的键,对值进行排序
推荐写法
- 先使用内置函数sorted,根据key对字典排序
- 再使用推导式,获取value列表
- 关于sorted函数的用法,参看章节“根据key对字典排序”
dict1 = {"a": 3, "c": 1, "b": 2}
list1 = sorted(dict1.items(), key=lambda item: item[0])
print(list1) # 根据key对字典排序 [('a', 3), ('b', 2), ('c', 1)]
list2 = [value for key, value in list1]
print(list2) # [3, 2, 1]
推荐写法
- 先使用内置函数sorted,对字典的键列表排序
- 再使用推导式,获取key对应的value
dict1 = {"a": 3, "c": 1, "b": 2}
keys = sorted(dict1.keys())
list1 = [dict1[k] for k in keys]
print(list1) # [3, 2, 1]
推荐写法
- 先使用内置函数sorted,对字典的键列表排序
- 再使用内置函数map,获取key对应的value
- 由于Python3.x版本中,map函数的返回一个迭代器(Python2.x版本中map返回一个列表),需要使用内置类list(iterable)进行转换
dict1 = {"a": 3, "c": 1, "b": 2}
keys = sorted(dict1.keys())
list1 = list(map(dict1.get, keys))
print(list1) # [3, 2, 1]
3) 根据value对字典排序
根据value,对字典进行排序
推荐写法: 使用Python3的标准库,内置函数:sorted(iterable[, key=None[, reverse=False]),key和reverse是可选参数
- 用法同上
dict1 = {"a": 3, "c": 1, "b": 2}
# item指代(键,值)元组,item[0]是键, item[1]是值
# 正序
dict_sorted = sorted(dict1.items(), key=lambda item: item[1])
print(dict_sorted) # [('c', 1), ('b', 2), ('a', 3)]
# 逆序
dict_sorted_rev = sorted(dict1.items(), key=lambda item: item[1], reverse=True)
print(dict_sorted_rev) # [('a', 3), ('b', 2), ('c', 1)]
4) 根据某个key对应的value对字典列表排序
根据字典中某个key对应的value,对字典列表进行排序
*推荐写法: 使用Python3的标准库,operator模块的类:itemgetter(keys)
- 需要导入operator模块的itemgetter
- keys用于指定键,接受多个key参数,多个参数使用逗号”,“隔开
from operator import itemgetter
stu = [
{"id": 3, "name": "Tom", "score": 82},
{"id": 2, "name": "Jerry", "score": 67},
{"id": 1, "name": "Pig", "score": 82},
{"id": 4, "name": "Dog", "score": 98},
]
# 根据key"score"对应的value 对stu正序排序
'''
[{'id': 2, 'name': 'Jerry', 'score': 67},
{'id': 3, 'name': 'Tom', 'score': 82},
{'id': 1, 'name': 'Pig', 'score': 82},
{'id': 4, 'name': 'Dog', 'score': 98}]
'''
sorted_by_score = sorted(stu, key=itemgetter("score"))
print(sorted_by_score)
# 根据key"score"对应的value 对stu逆序排序
'''
[{'id': 4, 'name': 'Dog', 'score': 98},
{'id': 3, 'name': 'Tom', 'score': 82},
{'id': 1, 'name': 'Pig', 'score': 82},
{'id': 2, 'name': 'Jerry', 'score': 67}]
'''
sorted_by_score_rev = sorted(stu, key=itemgetter("score"), reverse=True)
print(sorted_by_score_rev)
# 根据key"score"和"id" 对stu正序排序(先根据"score"排序,"score"相同的情况下根据"id"排序)
'''
[{'id': 2, 'name': 'Jerry', 'score': 67},
{'id': 1, 'name': 'Pig', 'score': 82},
{'id': 3, 'name': 'Tom', 'score': 82},
{'id': 4, 'name': 'Dog', 'score': 98}]
'''
rows_by_score_id = sorted(stu, key=itemgetter("score", "id"))
print(rows_by_score_id)
*推荐写法: 使用Python3的标准库,内置函数:sorted(iterable, , key=None, reverse=False)
- 接受多个key参数,多个参数使用逗号”,“隔开
stu = [
{"id": 3, "name": "Tom", "score": 82},
{"id": 2, "name": "Jerry", "score": 67},
{"id": 1, "name": "Pig", "score": 82},
{"id": 4, "name": "Dog", "score": 98},
]
# 根据key"score"对应的value 对stu正序排序
'''
[{'id': 2, 'name': 'Jerry', 'score': 67},
{'id': 3, 'name': 'Tom', 'score': 82},
{'id': 1, 'name': 'Pig', 'score': 82},
{'id': 4, 'name': 'Dog', 'score': 98}]
'''
sorted_by_score = sorted(stu, key=lambda item: item["score"])
print(sorted_by_score)
# 根据key"score"对应的value 对stu逆序排序
'''
[{'id': 4, 'name': 'Dog', 'score': 98},
{'id': 3, 'name': 'Tom', 'score': 82},
{'id': 1, 'name': 'Pig', 'score': 82},
{'id': 2, 'name': 'Jerry', 'score': 67}]
'''
sorted_by_score_rev = sorted(stu, key=lambda item: item["score"], reverse=True)
print(sorted_by_score_rev)
# 根据key"score"和"id" 对stu正序排序(先根据"score"排序,"score"相同的情况下根据"id"排序)
'''
[{'id': 2, 'name': 'Jerry', 'score': 67},
{'id': 1, 'name': 'Pig', 'score': 82},
{'id': 3, 'name': 'Tom', 'score': 82},
{'id': 4, 'name': 'Dog', 'score': 98}]
'''
rows_by_score_id = sorted(stu, key=lambda item: (item["score"], item["id"]))
print(rows_by_score_id)
11. Dict运算
基于键值视图对象也支持Set运算(比如集合的并、交、差运算)这一重要特性,进行求并集、交集、差集、对称差集的字典间运算
1) 合并
合并两个字典,键是唯一的,值可以是任意的
推荐写法: 使用Python3的标准库,dict类内置函数:update(other),other指代一个字典对象
- 修改当前字典,添加新的元素或Dict到当前字典中
- 若key已存在,则会修改相应的值,若key不存在,则添加元素
a = {"one": 1, "two": 2, "three": 3}
b = {"one": 111, "three": 3, "four": 4}
a.update(b)
print(a) # key"one"的值被修改 {'one': 111, 'two': 2, 'three': 3, 'four': 4}
一般写法: 使用运算符”|“
- 返回一个新Dict
- 运算符”|“的作用对象是两个字典的键值对列表视图,而不是字典实例
- 若出现重复键,则第一个字典key对应的值会被使用,即它的值不会被修改
- 若原字典做了更新,不会影响新合并的字典
- 若新合并的字典更新了,这种改变总是影响第一个字典
a = {"one": 1, "two": 2, "three": 3}
b = {"one": 111, "three": 3, "four": 4}
c = dict(a.items() | b.items())
print(c) # key"one"的值没有被修改 {'four': 4, 'one': 1, 'three': 3, 'two': 2}
a.clear()
print(c) # 原字典改变 不会影响新合并的字典 {'four': 4, 'one': 1, 'three': 3, 'two': 2}
c.clear()
print(a) # 新合并的字典改变 影响第一个字典 {}
print(b) # 新合并的字典改变 不会影响第二个字典 {'one': 111, 'three': 3, 'four': 4}
一般写法: 使用Python3的标准库,collections模块的类:ChainMap(*maps)
- 需要导入collections模块的ChainMap
- 返回一个新Dict
- 若出现重复键,则第一个字典key对应的值会被使用,即它的值不会被修改
- 若原字典做了更新,会影响新合并的字典
- 若新合并的字典更新了,这种改变总是影响第一个字典
from collections import ChainMap
a = {"one": 1, "two": 2, "three": 3}
b = {"one": 111, "three": 3, "four": 4}
c = ChainMap(a, b)
print(c) # ChainMap({'one': 1, 'two': 2, 'three': 3}, {'one': 111, 'three': 3, 'four': 4})
print(c["one"]) # 1 (from a)
print(c["two"]) # 2 (from a)
print(c["three"]) # 3 (from a)
print(c["four"]) # 4 (from b)
a.clear()
print(c) # ChainMap({}, {'one': 111, 'three': 3, 'four': 4})
print(c["two"]) # 原字典改变 影响新合并的字典 抛出KeyError: 'two'
c.clear()
print(a) # 新合并的字典改变 影响第一个字典 {}
print(b) # 新合并的字典改变 不会影响第二个字典 {'one': 111, 'three': 3, 'four': 4}
2) 交集
从第一个字典中移除与第二个字典不相同的键值对
一般写法: 使用运算符”&“
- 返回一个新Dict
- 运算符”&“的作用对象是两个字典的键值对列表视图,而不是字典实例
- 从第一个字典中移除与第二个字典不相同的键值对
- 若原字典做了更新,不会影响新字典
- 若新字典更新了,这种改变总是影响第一个字典
a = {"one": 1, "two": 2, "three": 3}
b = {"one": 111, "three": 3, "four": 4}
c = dict(a.items() & b.items())
print(c) # {'three': 3}
a.clear()
print(c) # 原字典改变 不会影响新字典 {'three': 3}
c.clear()
print(a) # 新字典改变 影响第一个字典 {}
print(b) # 新字典改变 不会影响第二个字典 {'one': 111, 'three': 3, 'four': 4}
3) 差集
从第一个字典中移除与第二个字典相同的键值对
一般写法: 使用运算符”-“
- 返回一个新Dict
- 运算符”-“的作用对象是两个字典的键值对列表视图,而不是字典实例
- 从第一个字典中移除与第二个字典相同的键值对
- 若原字典做了更新,不会影响新字典
- 若新字典更新了,这种改变总是影响第一个字典
a = {"one": 1, "two": 2, "three": 3}
b = {"one": 111, "three": 3, "four": 4}
c = dict(a.items() - b.items())
print(c) # {'two': 2, 'one': 1}
a.clear()
print(c) # 原字典改变 不会影响新字典 {'two': 2, 'one': 1}
c.clear()
print(a) # 新字典改变 影响第一个字典 {}
print(b) # 新字典改变 不会影响第二个字典 {'one': 111, 'three': 3, 'four': 4}
4) 对称差集
从第一个字典中移除与第二个字典相同的键值对,并将第二个字典中特有的键值对插入到当前字典中
一般写法: 使用运算符”^“
- 返回一个新Dict
- 运算符”^“的作用对象是两个字典的键值对列表视图,而不是字典实例
- 从第一个字典中移除与第二个字典相同的键值对,并将第二个字典中特有的键值对插入到当前字典中
- 若原字典做了更新,不会影响新字典
- 若新字典更新了,这种改变总是影响第一个字典
a = {"one": 1, "two": 2, "three": 3}
b = {"one": 111, "three": 3, "four": 4}
c = dict(a.items() ^ b.items())
print(c) # {'four': 4, 'one': 1, 'two': 2}
a.clear()
print(c) # 原字典改变 不会影响新字典 {'four': 4, 'one': 1, 'two': 2}
c.clear()
print(a) # 新字典改变 影响第一个字典 {}
print(b) # 新字典改变 不会影响第二个字典 {'one': 111, 'three': 3, 'four': 4}
5) 补集
A相对于B中的补集是指B中移除与A相同的键值对的字典
推荐写法: 使用运算符“-”
- 返回一个新Dict,不会修改当前Dict
a = {"one": 1, "two": 2, "three": 3}
b = {"one": 1, "two": 2}
c = {"one": 111, "two": 2}
# b相对于a的绝对补集(a包含b)
b_a = a.items() - b.items()
print(b_a) # {('three', 3)}
# b相对于c的相对补集(c和b有交集但是c不包含b)
b_c = c.items() - b.items()
print(b_c) # {('one', 111)}
6) 过滤请求参数
keys_to_remove = ("param0", "param1", "param2", "uuid")
list(map(lambda x: functools.partial(request_body.pop, x, None)(), keys_to_remove))
for key in list(request_body.keys()):
if request_body.get(key) == 0:
continue
if not request_body.get(key):
request_body.pop(key)